C ++使用WaitForMultipleObjects检测哪个线程完成

时间:2015-03-30 13:29:35

标签: c++ multithreading waitformultipleobjects

我正在尝试同时运行3个线程,然后在主线程中检测到哪个线程已完成。我正在使用WaitForMultipleObject函数,但第三个线程似乎为这个WFMO函数循环,而它已经完成了它的工作(打印结果)。

    #include <Windows.h>
    #include <stdio.h>
    #include <conio.h>
    //---------------------------------------------------------------------------
    #pragma argsused
    struct data 
    {
        char name[50];
    } data[3] = { { "[THREAD 0]" }, { "[THREAD 1]" },{ "[THREAD 2]" } };

    DWORD WINAPI th0()
{
    //here are some calculations
    //also added 1s sleep

    //printing result
    return 0;

}
DWORD WINAPI th1()
{
    //here are some other calculations
    //also added 1s sleep

    //printing result

    return 0;
}
DWORD WINAPI th2()
{
    //here are some other simple calculations
    //also added 1s sleep


    //printing result
    return 0;
}


    int priority[3] = { 0,0, 0};
    HANDLE threads[3]; 
    HANDLE functions[3];


    int main(int argc, char **argv)
    {
        int i;
        DWORD id; // thread's id

        printf("Program started...\n");

        functions[0] = th0;
        functions[1] = th1;
        functions[2] = th2; 
        for (i = 0; i < 3; i++)
        {
            threads[i] = CreateThread(
                NULL, // security atributes
                0, // stack size
                (LPTHREAD_START_ROUTINE)functions[i], // threads
                NULL,// input data for threads
                0, // creation's flags
                &id);//thread's id
            if (threads[i] != INVALID_HANDLE_VALUE)
            {
                printf("Created thread %s with ID: %x\n",
                    data[i].name, id);          
                SetThreadPriority(threads[i], priority[i]);
            }
        }
        bool f0=false, f1=false, f2=false;
        while(!f0 || !f1 || !f2)//while there is any unfinished thread
        {
            DWORD wfmo = WaitForMultipleObjects(3, threads, false, INFINITE);

            if (!f0 && WAIT_OBJECT_0==wfmo)
            {
                printf("%s is done!\n", data[0].name);
                f0=true;
                //CloseHandle(threads[0]);
                //threads[0]=NULL;

            }
            if (!f1 && WAIT_OBJECT_0 +1 == wfmo)
            {
                printf("%s is done!\n", data[1].name);
                f1=true;
                //CloseHandle(watki[1]);
                //watki[1]=NULL;

            }
            if (!f2 && WAIT_OBJECT_0 +2 == wfmo)
            {
                printf("%s is done!\n", data[2].name);
                f2=true;
                //CloseHandle(threads[2]);
                //threads[2]=NULL;
            }
            if(wfmo==WAIT_TIMEOUT)
                printf("timeout\n");
            if(wfmo==WAIT_FAILED)
                printf("failed\n");
        }


        //Sleep(20000); //20s
        return 0;
    }

输出:

    Program started... 
    Created thread [THREAD 0] with ID: b00 
    Created thread [THREAD 1] with ID: a64 
    Created thread [THREAD 2] with ID: 7d0 
    [THREAD 2] Result: 131072 
    [THREAD 1] Result: 121393 
    [THREAD 0] Result: 362880 
    [THREAD 2] is done! 
    [THREAD 0] is done!

2 个答案:

答案 0 :(得分:0)

来自MSDN WaitForMultipleObjects文档:

  

如果bWaitAll为FALSE,则返回值减去WAIT_OBJECT_0表示满足等待的对象的lpHandles数组索引。如果在调用期间发出多个对象的信号,则这是信号对象的数组索引,其中所有信号对象的索引值最小。

线程0完成后,返回值将始终为WAIT_OBJECT_0

答案 1 :(得分:0)

解决方案(而不是while循环):

DWORD wfmo = WaitForMultipleObjects(3, threads, false, INFINITE);
//HANDLE threads2[2];   
if ( WAIT_OBJECT_0==wfmo)//move th1 and th2 up 
{
    printf("%s is done!\n", data[0].name);
    threads[0]=threads[1];
    threads[1]=threads[2];
    data[0]=data[1];
    data[1]=data[2];
    threads[2]=NULL;

}
else if ( WAIT_OBJECT_0 +1 == wfmo) //move th2 up
{
    printf("%s is done!\n", data[1].name);      
    threads[1]=threads[2];
    data[1]=data[2];
    threads[2]=NULL;
}
else if (  WAIT_OBJECT_0 +2 == wfmo)//no need to do anything
{
    printf("%s is done!\n", data[2].name);
    threads[2]=NULL;
}

wfmo = WaitForMultipleObjects(2, threads, false, INFINITE); 
if ( WAIT_OBJECT_0==wfmo)       
{
    printf("%s is done!\n", data[0].name);
    threads[0]=threads[1];
    data[0]=data[1];
    threads[1]=NULL;
}
else if ( WAIT_OBJECT_0 +1 == wfmo)     
{
    printf("%s is done!\n", data[1].name);

    threads[1]=NULL;
}

wfmo = WaitForMultipleObjects(1, threads, false, INFINITE);
if ( WAIT_OBJECT_0==wfmo)   
    printf("%s is done!\n", data[0].name);