静态线程标志和-O3

时间:2020-09-22 07:40:02

标签: c multithreading

我尝试编写单个生产者使用者实现。 使用优化进行编译时遇到问题。 在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;
}```

2 个答案:

答案 0 :(得分:0)

如果您在编写编译器,并且发现了

while(flag == 1)
   ;

你会怎么做?我会对其进行优化,因为flag不可能在循环内更改。

但是,在某些情况下,flag可能会在您不知情的情况下发生其他变化。这就是volatile的目的:它告诉编译器期望意外的结果。

答案 1 :(得分:0)

volatile向编译器显示对象是“容易产生副作用”的,这意味着可以用正常程序执行路径中没有的内容来更改它。

每次使用

voaltile对象时,都会从其内存位置读取该对象。程序每次修改后都会更新其内存存储空间

在这里很容易发现差异。 https://godbolt.org/z/s1beqq