我是新来的,我希望我做的一切都是正确的。
我想知道如何在等待使用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行。我认为这个片段就足够了。
答案 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;});
我强烈推荐这种类型的包装,因为在一天结束时,编译器会将其优化为相同的代码,但是你不能犯很多错误。