我尝试编写单个生产者使用者实现。 使用优化进行编译时遇到问题。 在gcc中使用优化(-O3)运行时,线程卡住了。
在添加volatile或从全局标志中删除static时,线程按预期工作。 为什么会这样?
#include <stdio.h>
#include <pthread.h>
static volatile int flag = 0; /* this is the line */
static int resource = 0;
void *Writer(void *somthing);
void *Reader(void *somthing);
int main()
{
pthread_t id1 = 0;
pthread_t id2 = 0;
pthread_create(&id1, NULL, Writer, NULL);
pthread_create(&id2, NULL, Reader, NULL);
return 0;
}
void *Writer(void *somthing)
{
while(1)
{
while (1 == flag);
++resource;
flag = 1;
}
return NULL;
}
void *Reader(void *somthing)
{
while(1)
{
while(0 == flag);
fprintf(stderr,"%d\n",resource);
flag = 0;
}
return NULL;
}```
答案 0 :(得分:0)
如果您在编写编译器,并且发现了
while(flag == 1)
;
你会怎么做?我会对其进行优化,因为flag
不可能在循环内更改。
但是,在某些情况下,flag
可能会在您不知情的情况下发生其他变化。这就是volatile
的目的:它告诉编译器期望意外的结果。
答案 1 :(得分:0)
volatile
向编译器显示对象是“容易产生副作用”的,这意味着可以用正常程序执行路径中没有的内容来更改它。
voaltile
对象时,都会从其内存位置读取该对象。程序每次修改后都会更新其内存存储空间
在这里很容易发现差异。 https://godbolt.org/z/s1beqq