Question

 #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;
}

The function InterlockedIncrement ensure the operation of g_cnt++ is atomic operation. The final value of g_cnt should be 1000, but sometimes it is less than 1000, why?

Note:As @manuell said, WaitForMultipleObjects wait for MAXIMUM_WAIT_OBJECTS objects at most. MAXIMUM_WAIT_OBJECTS = 64 on my machine. So WaitForMultipleObjects(threadNum, hth, TRUE, INFINITE); should be replaced by:

        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);

Test environment: win7 X64 , codeblocks with gcc4.7.1

Was it helpful?

Solution

Because your code doesn't works as expected. Test the error conditions.

For one, you can't wait on 1000 handles in a single call to WaitForMultipleObjects, so the call fails, so you don't know how many threads are still running when you read g_cnt.

On my current environment, MAXIMUM_WAIT_OBJECTS is 64.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top