2011-10-20 42 views
1

我希望得到从0号码4在随机顺序,而是,我有一些不同步的混乱简单的多线程互斥的例子是不正确

我该怎么办了?

#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

[“你还能够使用由_beginthreadex与同步的API返回线程句柄,**你不能用_beginthread做。**”(http://msdn.microsoft.com/en-us/库/ 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(); 
} 

如果可以,用一个关键部分,而不是一个互斥体,因为它们更易于使用,更高效。但是它们具有相同的语义,因为它们只保护锁定块内的代码。

注:杰里具有指针出一些其他的问题,但我已经集中在高层次trheading和系列化的担忧。

+0

谢谢!全局'int counter'的例子对我来说很清楚。但我怎么可以传递一些数据创建线程函数? – triclosan

+0

你通过它,你在做同样的方式,而不是指向一个循环计数器! –

-1

你​​是没有错的!

的问题是,你得到的变量i在功能addQuery参数的地址 - 当第一个线程运行 - 它并不保证i的值仍为0,因为在此期间它可能已被更改到你循环中的下一个值。

您可能需要的代码David Heffernan的回复。