哪个线程以多线程结束

Which thread finishes with multithreading?

本文关键字:多线程 结束 线程      更新时间:2023-10-16

我刚来这里,希望我做的每件事都很好。

我想知道如何在等待一个线程使用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行。我想这个片段就足够了。

当第三个参数是false时,一旦有任何对象发出信号,WaitForMultipleObjects就会返回(不需要等待所有对象)。

返回值指示是哪个对象导致它返回。第一个对象将为WAIT_OBJECT_0,第二个对象为WAIT_OBJECT_0 + 1,依此类推。

我离开了我的编译器,我不知道有什么能与windows一起工作的online 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;
}

在工作中,我们的做法有点不同。我们制作了一个库,它封装了所有需要的窗口句柄类型和预成型静态类型检查(通过转换运算符),以确保您不能等待IOCompletionPortWaitForMultipleObjects(这是不允许的)。等待函数是可变的,而不是采用句柄及其大小的数组,并且当只有一个句柄时,使用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;});

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