1

我尝试编写一个物理模拟程序。我使用两个线程,一个用于计算,一个用于 gui。为了在它们之间交换数据,我使用了一个结构

struct sim_data {  
     int running;  
     int steps;  
    int progress;  
 ...  
};

并将其包含在不同的线程中

void *sim(void *args) {  
    struct sim_data *my_data;  
    my_data=(struct sim_data *)args;  
    ...  
}

设置值时

my_data->progress=1000;

数据在同一个线程中可用,但在第二个线程中不可靠。当启动程序在第二个线程中读取不同的值然后在第一个线程中写入时,我猜想有 10% 的机会。虽然数据是循环写入的,但我认为这不是时间问题。

我觉得这很奇怪。任何猜测出了什么问题?

4

2 回答 2

1

C++11 规范将数据竞争情况声明为一个线程写入某个位置而第二个线程可以读取或写入该位置的任何时候。它声明当这种情况发生时你会得到未定义的行为。在您的情况下,一个线程正在写入 my_data->progress 而另一个线程正在读取它。

解决方案是使用同步,例如原子整数或锁定。

C++ 编译器进行了非常令人印象深刻的优化,以使您的单线程程序运行得更快。例如,它可能证明,在单线程世界中,没有办法看到 1000 的值,而干脆选择不打印它。

还有更多丑陋的案件是合法的。如果编译器知道您想要存储 1000,它可能会选择根本不存储任何内容,而是使用该内存作为空间以将临时结果“溢出”到其中,而不是分配更多空间,然后最终存储 1000。期间同时,您可以读取任意值。

对于这个问题的相当幽默的看法:http: //software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-c ​​ould-possibly-go-wrong

于 2013-09-01T05:25:28.837 回答
0

最简单的解决方案:

struct sim_data {  
     int running;  
     int steps;  
     atomic<int> progress;  //this will guarantee the data are coherent between two threads
 ...  
};
于 2017-08-10T18:07:55.067 回答