哪个线程完成多线程?

时间:2013-12-10 20:51:30

标签: c++ multithreading

我是新来的,我希望我做的一切都是正确的。

我想知道如何在等待使用WaitForMultipleObjects命令完成后找出哪个线程完成。目前我有以下几点:

int checknum;
int loop = 0;
const int NumThreads = 3;

HANDLE threads[NumThreads];

WaitForMultipleObjects(NumThreads, threads, false, INFINITE);
threads[loop] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0);

它应该最多同时运行三个线程。所以我有一个循环来开始所有三个线程(因此循环值)。问题是,当我再次浏览它时,我想将循环的值更改为刚刚完成其任务的任何线程的值,以便可以再次使用它。有没有办法找出该数组中的哪个线程已经完成?

我会粘贴剩余的代码,但我很确定没有人需要它的所有147行。我认为这个片段就足够了。

2 个答案:

答案 0 :(得分:2)

当第三个参数为false时,WaitForMultipleObjects将在任何对象发出信号后立即返回(它不需要等待所有对象)。

返回值表示哪个对象导致它返回。第一个对象为WAIT_OBJECT_0,第二个对象为WAIT_OBJECT_0 + 1,等等。

答案 1 :(得分:0)

我离开了我的编译器而且我不知道一个与windows兼容的onlione IDE,但这里是你需要做的粗略概念。

const int NumThreads = 3;
HANDLE threads[NumThreads];
//create threads here
DWORD result = WaitForMultipleObjects(NumThreads, threads, false, INFINITE);
if(result >= WAIT_OBJECT_0 && result - WAIT_OBJECT_0 < NumThreads){
    int index = result - WAIT_OBJECT_0;
    if(!CloseHandle(Handles[index])){ //need to close to give handle back to system even though the thread has finished 
        DWORD error = GetLastError();
        //TODO handle error
    }
    threads[index] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0);
}
else {
    DWORD error = GetLastError();
    //TODO handle error
    break;
}

在工作中我们这样做有点不同。我们创建了一个包含所有需要的窗口句柄类型的库,并预先形成静态类型检查(通过转换操作符),以确保您不能等待IOCompletionPort WaitForMultipleObjects(不是允许)。 wait函数是可变参数而不是取一个句柄数组及其大小,并且当只有一个时,使用SFINAE专门使用WaitForSingleObject。它还将Lambdas作为争论并根据发出信号的事件执行相应的争议。

这就是它的样子:

Win::Event ev;
Win::Thread th([]{/*...*/ return 0;});
//...

Win::WaitFor(ev,[]{std::cout << "event" << std::endl;},
        th,[]{std::cout << "thread" << std::endl;},
        std::chrono::milliseconds(100),[]{std::cout << "timeout" << std::endl;});

我强烈推荐这种类型的包装,因为在一天结束时,编译器会将其优化为相同的代码,但是你不能犯很多错误。