1

我想了解更多关于 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' 不允许修改任何其他功能标志。标志由它们自己的函数和调用函数修改。(为此,想象标志启用主线程和线程之间的通信。)

这是否解决了数据竞争问题,还是仍然是一个问题?

4

1 回答 1

4

这不是您要问的具体内容,而是flag应该是atomic<char>*或者您有数据竞赛,即未定义的行为。此外,如果它只持有 true 或 false 我会使用atomic<bool>*并且只是 test 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]代表一个正在运行的线程并且再次“可加入”。

于 2013-07-04T16:31:17.460 回答