2

我试图同时运行 3 个线程,然后在主线程中检测哪个线程已经完成。我正在使用 WaitForMultipleObject 函数,但第 3 个线程似乎为这个 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!
4

2 回答 2

1

从 MSDNWaitForMultipleObjects文档:

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

一旦线程 0 完成,返回值将始终为WAIT_OBJECT_0.

于 2015-03-30T13:39:21.847 回答
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);
于 2015-03-30T14:18:56.870 回答