c - GCC优化对线程并发的影响

标签 c multithreading gcc optimization

我只是摆弄线程并观察在修改不 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/

相关文章:

java多线程(newCachedThreadPool),然后将结果写入一个文件?

c# - 在方法执行代码时显示进度表的最佳方式?

C - Fclose -> 中止(核心转储)

c - 树莓派上的 SDL 1.2 出现奇怪的线程死锁

c - 从 TCP 数据包负载中获取主机字段

c - 为什么我的所有线程都使用 sleep() 进行 sleep ?

gcc,不同架构上 long int 的宽度

c - 为什么 "X"可以是输出的最后一个字符?

c - 在 Linux 上,当使用 C 执行与端口 0(选择一个随机端口)的套接字绑定(bind)时,我得到 errno 98,Address already in use。这怎么可能?

Linux:调试信息格式 "stabs"英文缩写是什么?