我只是摆弄线程并观察在修改不 protected 全局变量时竞争条件是如何发生的。具有 3 个线程的简单程序在具有 100000 次迭代的紧密循环中递增全局变量 -
#include <stdio.h>
#include <pthread.h>
static int global;
pthread_mutex_t lock;
#define LOCK() pthread_mutex_lock(&lock)
#define UNLOCK() pthread_mutex_unlock(&lock)
void *func(void *arg)
{
int i;
//LOCK();
for(i = 0; i < 100000; i++)
{
global++;
}
//UNLOCK();
}
int main()
{
pthread_t tid[3];
int i;
pthread_mutex_init(&lock, NULL);
for(i = 0; i < 3; i++)
{
pthread_create(&tid[i], NULL, func, NULL);
}
for(i = 0; i < 3; i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&lock);
printf("Global value: %d\n", global);
return 0;
}
当我使用 -g 标志编译它并运行该对象 5 次时,我得到了这个输出:
Global value: 300000
Global value: 201567
Global value: 179584
Global value: 105194
Global value: 205161
这是预期的。经典同步问题在这里。没什么可看的。 但是当我用优化标志-O 编译时。我得到这个输出:
Global value: 300000
Global value: 100000
Global value: 100000
Global value: 100000
Global value: 200000
这部分对我来说没有意义。 GCC 优化了什么,使线程在整个 1/3 或 2/3 的总迭代中处于竞争状态?
最佳答案
循环可能被优化为读取全局变量一次,执行所有增量,然后将其写回。输出的差异取决于循环是否重叠。
关于c - GCC优化对线程并发的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43596167/