Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当函数执行结束时,向量中的线程会发生什么情况?_C++_Multithreading_C++11 - Fatal编程技术网

C++ 当函数执行结束时,向量中的线程会发生什么情况?

C++ 当函数执行结束时,向量中的线程会发生什么情况?,c++,multithreading,c++11,C++,Multithreading,C++11,我想了解更多关于std::thread的信息,特别是如果我有一个线程向量,并且其中一个线程完成了执行,将会发生什么 想象一下这个例子: 创建一个线程向量,所有线程都执行以下函数: function_test(char* flag) { while(*flag == 1) { // Do Something } } “char*flag”指向一个标志,表示函数停止执行 例如,向量包含10个线程,它们都在执行。然后,3号线程的标志设置为零。(向量中的第四个线程,因为向量从零开始。)

我想了解更多关于std::thread的信息,特别是如果我有一个线程向量,并且其中一个线程完成了执行,将会发生什么

想象一下这个例子:

创建一个线程向量,所有线程都执行以下函数:

function_test(char* flag)
{
    while(*flag == 1) { // Do Something
    }
}
“char*flag”指向一个标志,表示函数停止执行

例如,向量包含10个线程,它们都在执行。然后,3号线程的标志设置为零。(向量中的第四个线程,因为向量从零开始。)

好的做法是,然后加入线程

vector_of_threads[3].join();
向量现在将包含多少std::线程?我可以用相同的函数重新启动已完成的线程吗,或者甚至可以使用不同的函数

我提出这个问题的原因是,我有一个线程向量,有时需要它们停止执行,然后执行“从函数的末尾掉下来”

重新启动该线程的一个解决方案(我假设,可能是错误的?)是从向量中删除该元素,然后插入一个新线程,该线程将开始执行。但是这是正确的吗?因为当线程停止时,它还会在向量中吗?我想是吧

编辑

“function_test”不允许修改任何其他函数标志。这些标志由它们自己的函数和调用函数修改。(为此,imagine标志启用主线程和线程之间的通信。)


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

这不是您要问的具体问题,但是
标志应该是
原子*
,或者您有一个未定义的行为。另外,如果它只支持true或false,我会使用
atomic*
并只测试
if(*标志)

至于你的实际问题:

向量现在将包含多少std::线程

它将包含与以前完全相同的数字,但其中一个不再是“可连接的”,因为它不表示正在运行的线程。当线程停止运行时,它不会神奇地改变向量以删除元素,它甚至不知道向量存在!在主线程中唯一可见的变化是调用
vector\u of_threads[3].join()
不会被阻止,并且会立即返回,因为线程已经完成,所以您不必等待加入它

您可以从向量中删除连接的
std::thread
,并插入一个新的,但另一种选择是为它分配另一个
std::thread
,它表示一个新的执行线程:

vector_of_threads[3] = std::thread(f, &flags[3]);

现在,
vector\u of_threads[3]
表示一个正在运行的线程,并且再次是“可连接的”。

这并不是你要问的具体问题,但是
标志应该是
原子*
或者你有一个未定义的行为。另外,如果它只支持true或false,我会使用
atomic*
并只测试
if(*标志)

至于你的实际问题:

向量现在将包含多少std::线程

它将包含与以前完全相同的数字,但其中一个不再是“可连接的”,因为它不表示正在运行的线程。当线程停止运行时,它不会神奇地改变向量以删除元素,它甚至不知道向量存在!在主线程中唯一可见的变化是调用
vector\u of_threads[3].join()
不会被阻止,并且会立即返回,因为线程已经完成,所以您不必等待加入它

您可以从向量中删除连接的
std::thread
,并插入一个新的,但另一种选择是为它分配另一个
std::thread
,它表示一个新的执行线程:

vector_of_threads[3] = std::thread(f, &flags[3]);

现在,
vector\u of_threads[3]
表示一个正在运行的线程,并且再次是“可连接的”。

好吧,那太好了,你能给我解释一下数据竞争,以及这种情况是如何发生的吗?@EdwardBird,一个线程执行
如果(*flag==1)
并且在某个点上,另一个线程设置
flags[3]=1
,如果这些线程之间没有同步,那么对同一内存位置的读写就会发生冲突:这是一个数据竞争。必须对其进行修改,否则它如何从初始值更改为
1
?因此一个线程读取它,一个线程写入它。这是一场数据竞赛,这仍然是一场数据竞赛!将其设置为0(即写入内存位置)的行为,即使只有一次,也与在另一个线程中读取它的行为相冲突。好的,这很好,您能给我解释一下数据竞争,以及如何/为什么会发生这种情况吗?@EdwardBird,如果(*flag==1),一个线程执行
在某个点上,另一个线程设置
标志[3]=1
,这些线程之间不同步,您对同一内存位置的读写发生冲突:这是一个数据竞争。必须对其进行修改,否则它如何从其初始值更改为
1
?因此一个线程读取它,一个线程编写它。这是一场数据竞赛,这仍然是一场数据竞赛!将其设置为0(即写入内存位置)的行为,即使只有一次,也与在另一个线程中读取它的行为相冲突。