我想了解更多关于std :: thread的信息,特别是如果我有一个线程向量,并且其中一个线程完成执行会发生什么。
想象一下这个例子:
创建一个线程向量,它们都执行以下函数:
function_test(char* flag)
{
while(*flag == 1) { // Do Something
}
}
' char * flag'指向一个标志信号表示停止执行的功能。
例如,假设向量包含10个线程,这些线程都在执行。然后,对于第3个线程,该标志设置为零。(向量中的第4个线程,因为向量从零开始。)
好的做法是加入线程。
vector_of_threads[3].join();
向量现在包含多少std :: threads?我可以再次使用相同的功能重新启动完成的线程,甚至是不同的功能吗?
我的问题的原因是我有一个线程向量,有时它们将被要求停止执行,然后执行"掉线到最后"功能。
重新启动该线程的一个解决方案(我假设,可能不正确?)是从向量中删除该元素然后插入一个新线程,然后该线程将开始执行。这是正确的,因为当一个线程停止时,它仍然在向量内吗?我想它会是?
修改
' function_test'不允许修改任何其他函数标志。标志由它们自己的函数和调用函数修改。 (出于此目的,imag flag启用main和线程之间的通信。)
这是解决数据争用问题,还是仍然存在问题?
答案 0 :(得分:4)
这不是您要求的具体内容,但flag
应为atomic<char>*
或您有data race,即未定义的行为。此外,如果它只有真或假,我会使用atomic<bool>*
并只测试if (*flag)
。
至于你的实际问题:
向量现在包含多少std :: threads?
它将包含与之前完全相同的数字,但其中一个不再是“可连接”,因为它不代表正在运行的线程。当线程停止运行时,它不会神奇地改变向量以移除元素,它甚至不知道向量存在!主线程中唯一可见的更改是调用vector_of_threads[3].join()
不会阻塞并立即返回,因为线程已经完成,所以您不必等待加入它。
你可以从向量中删除联接的std::thread
并插入一个新的,但是另一个选择是为它分配另一个std::thread
来代表一个新的执行线程:
vector_of_threads[3] = std::thread(f, &flags[3]);
现在vector_of_threads[3]
代表一个正在运行的线程,并且再次“可加入”。