Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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+;中的bool变量时,是否可能出现争用条件+;?_C++_Multithreading_Synchronization_Race Condition - Fatal编程技术网

C++ 当只有一个线程写入c+;中的bool变量时,是否可能出现争用条件+;?

C++ 当只有一个线程写入c+;中的bool变量时,是否可能出现争用条件+;?,c++,multithreading,synchronization,race-condition,C++,Multithreading,Synchronization,Race Condition,在下面的代码示例中,程序执行永远不会结束 它创建一个线程,在终止之前等待全局bool设置为true。只有一个作者和一个读者。我认为允许循环继续运行的唯一情况是bool变量为false bool变量如何可能在只有一个writer的情况下处于不一致的状态 #包括 #包括 #包括 bool done=false; void*threadfunc1(void*){ std::cout在threadfunc1()中的这个语句有一个问题: 可以由编译器实现,如下所示: a_register =

在下面的代码示例中,程序执行永远不会结束

它创建一个线程,在终止之前等待全局
bool
设置为
true
。只有一个作者和一个读者。我认为允许循环继续运行的唯一情况是
bool
变量为false

bool
变量如何可能在只有一个writer的情况下处于不一致的状态

#包括
#包括
#包括
bool done=false;
void*threadfunc1(void*){

std::cout在
threadfunc1()
中的这个语句有一个问题:

可以由编译器实现,如下所示:

       a_register = done;
   label:
       if (a_register == 0) goto label;

因此,对
done
的更新将永远不会被看到。

实际上没有任何东西阻止编译器优化while循环。使用原子或互斥体从多个线程访问bool。这是唯一受支持且正确的解决方案。在这种情况下,使用posix时,互斥体将是正确的解决方案

而且不要使用
volatile
。posix标准规定了必须工作的内容,并且
volatile
不是保证工作的解决方案


还有另一个问题:在将标志设置为false之前,无法保证新创建的线程每次都开始运行。

争用条件意味着:当两个线程访问同一对象时,其中至少有一个线程是写线程

这意味着您将有两种类型的比赛,写-写冲突和写-读冲突

回到您的代码,您实际上有两个线程,一个是主线程,另一个是使用pthread_create创建的线程

其中一个是read:while(!done),另一个是write:done=true

你肯定有比赛条件

< P>是C++中只有一个线程写入布尔变量时可能的竞争条件?

是的。在您的情况下,主线程也是线程(即,您有一个线程写入和一个线程读取)

bool变量如何可能只与一个writer处于不一致的状态


编译器是(应该是)一个优化编译器。它可能会优化done变量的读取,除非您小心避免(改用
std::atomic done
).

对于这样一个简单的示例,不能保证对一个一字节的bool的赋值是原子的。

对于这样一个简单的示例,volatile就足够了。但对于绝大多数实际情况来说,这是不够的。使用条件变量来完成此任务。乍一看它们看起来很奇怪,但实际上它们是非常逻辑的。在x86上,bool是原子的,可以进行读/写(对于ARM,可能不是)。向量也有一个障碍:它不是布尔向量,而是位字段。要从多个线程写入向量,请使用向量(或布尔arr[SIZE])。
另外,您没有加入线程,这是错误的。

您观察到竞争条件了吗?无法复制-程序在1秒后终止访问bool变量不一定是一个原子操作。我不确定,但我相信非同步写入不能保证在我测试过的有限时间内对其他线程可见coliru谢谢你的回答。你的回答是唯一一个描述单编写器场景中不一致原因的答案。你确定吗?你能发布一些生成的汇编程序吗?这听起来像是meNo的编译器错误。不存在争用条件。对于易失性结果,不依赖于执行顺序(在x86上).Wait loop执行它应该执行的操作。对于实际任务,您需要在它之后添加障碍,但没有来自已创建线程的其他访问,因此这是可以的。无论如何,执行等待循环是一个坏主意,很容易错过一些内容。为此模式创建了条件变量。
   while(!done);
       a_register = done;
   label:
       if (a_register == 0) goto label;