2011-10-20 4 views
1
내가 임의의 순서로 4 0에서 숫자를 얻을 것으로 예상, 대신, 내가 어떤 동기화 엉망 내가 잘못된 일을

간단한 멀티 스레딩 뮤텍스의 예는 잘못

?

#include <iostream> 
#include <windows.h> 
#include <process.h> 

using namespace std; 

void addQuery(void *v); 

HANDLE ghMutex; 

int main() 
{ 
    HANDLE hs[5]; 
    ghMutex = CreateMutex(NULL, FALSE, NULL);   
    for(int i=0; i<5; ++i) 
    { 
     hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i); 
     if (hs[i] == NULL) 
     { 
      printf("error\n"); return -1; 
     } 
    } 

    printf("WaitForMultipleObjects return: %d error: %d\n", 
     (DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError()); 


    return 0; 
} 

void addQuery(void *v) 
{ 
    int t = *((int*)v); 
    WaitForSingleObject(ghMutex, INFINITE); 

    cout << t << endl; 

    ReleaseMutex(ghMutex); 
    _endthread(); 
} 
+0

[ "_beginthread와 함께 수행 할 수없는 동기화 API와 함께 _beginthreadex에서 반환 한 스레드 핸들을 사용할 수도 있습니다. **"] (http://msdn.microsoft.com/en-us/ library/kdzttdcb.aspx) –

답변

5

당신은 읽고 공유 변수 내부 잠금을 작성해야합니다. 자물쇠 외부에서이를 읽으므로 자물쇠가 적합하지 않게됩니다.

하지만 공유 변수가 잠금을 보호하지 않고 작성중인 루프 변수이기 때문에 충분하지 않습니다. 훨씬 더 좋은 예는 다음과 같이 실행됩니다 :

#include <iostream> 
#include <windows.h> 
#include <process.h> 

using namespace std; 

void addQuery(void *v); 

HANDLE ghMutex; 
int counter = 0; 

int main() 
{ 
    HANDLE hs[5]; 
    ghMutex = CreateMutex(NULL, FALSE, NULL);   
    for(int i=0; i<5; ++i) 
    { 
     hs[i] = (HANDLE)_beginthread(addQuery, 0, NULL); 
     if (hs[i] == NULL) 
     { 
      printf("error\n"); return -1; 
     } 
    } 

    printf("WaitForMultipleObjects return: %d error: %d\n", 
     (DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError()); 


    return 0; 
} 

void addQuery(void *v) 
{ 
    WaitForSingleObject(ghMutex, INFINITE); 

    cout << counter << endl; 
    counter++; 

    ReleaseMutex(ghMutex); 
    _endthread(); 
} 

들이 사용하기 간단하고 효율적 때문에, 뮤텍스보다는 중요한 섹션을 사용 할 수 있습니다. 그러나 잠금 블록 내부의 코드 만 보호한다는 점에서 동일한 의미를가집니다.

참고 : Jerry는 다른 문제를 지적하고 있지만 높은 수준의 trheading 및 serialization 문제에 집중했습니다.

+0

고마워요! 전역'int counter '예제는 나에게 분명합니다. 하지만 어떻게 내가 만든 스레드 함수에 일부 데이터를 전달할 수 있습니까? – triclosan

+0

루프 카운터에 대한 포인터가 아니라 동일한 방법으로 전달합니다! –

-1

synchronized이 잘못되었습니다. 첫 번째 스레드가 실행 중일 때 - - 그것은 i 여전히 0 값을 가지고 있음을 보장하지 않습니다 그 동안이 변경되었을 수 있기 때문에,

문제는 당신이 기능 addQuery의 매개 변수에 변수 i의 주소를 얻을 수 있다는 것입니다 루프의 다음 값으로

David Heffernan 님의 답변이 필요합니다.