多线程编程中win32 API InterlockedIncrement的意外结果

时间:2014-03-15 09:12:10

标签: multithreading winapi synchronization thread-synchronization

 #include<string>
 #include<iostream>
 #include<process.h>
 #include<windows.h>
 using namespace std;

volatile int g_cnt = 0;

unsigned __stdcall threadFun(void *param)
{
    InterlockedIncrement((LONG volatile *)&g_cnt);
    return 0;
}

int main()
{
    const int threadNum = 1000;
    HANDLE hth[threadNum];

    for(int i = 0; i < threadNum; i++)
        hth[i] = (HANDLE)_beginthreadex(NULL, 0, threadFun, NULL, 0, NULL);

    WaitForMultipleObjects(threadNum, hth, TRUE, INFINITE);

    for(int i = 0; i < threadNum; i++)
        CloseHandle(hth[i]);

    cout<<"the value of g_cnt: "<<g_cnt<<endl;
}

函数InterlockedIncrement确保g_cnt++的操作是原子操作。 g_cnt的最终值应为1000,但有时小于1000,为什么?

注意:正如@manuell所说,WaitForMultipleObjects最多等待MAXIMUM_WAIT_OBJECTS个对象。 MAXIMUM_WAIT_OBJECTS = 64在我的机器上。因此WaitForMultipleObjects(threadNum, hth, TRUE, INFINITE);应替换为:

        int k = threadNum / MAXIMUM_WAIT_OBJECTS;
        for(int i = 0; i < k; i++)
            WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS,
                                   &hth[i*MAXIMUM_WAIT_OBJECTS],
                                   TRUE, INFINITE);
        if(threadNum % MAXIMUM_WAIT_OBJECTS != 0)
            WaitForMultipleObjects(threadNum % MAXIMUM_WAIT_OBJECTS,
                                   &hth[k*MAXIMUM_WAIT_OBJECTS],
                                   TRUE, INFINITE);

测试环境:win7 X64,带有gcc4.7.1的代码块

1 个答案:

答案 0 :(得分:2)

因为您的代码无法按预期工作。 测试错误条件

首先,你不能在一次调用WaitForMultipleObjects时等待1000个句柄,因此调用失败,所以当你读g_cnt时你不知道还有多少线程在运行。

在我目前的环境中,MAXIMUM_WAIT_OBJECTS为64。