使用c ++ 11的std :: thread,什么时候修改全局变量是线程安全的?

 liqiqinai 发布于 2023-01-01 18:18

考虑这个来源:

#include 
#include 
#include 

using namespace std;

int *up;

void testf(){
    for(int i = 0; i < 1000; i++)
        for(int f = 0; f < 11; f++)
            up[i]++;
}

int main() {
    up = new int[1000];

    std::thread tt[7];

    for(int ts=0;ts<7;ts++) {
        tt[ts]=std::thread(testf);
    }

    for(int ts=0;ts<7;ts++) {
        tt[ts].join();
    }

    for(int i = 0; i < 1000; i++)
        cout << up[i];
    cout << endl;
    delete[] up;
    return 0;
}

我故意在没有任何互斥锁的情况下写入相同的int数组.for循环testf()将增加int up[1000]11的所有成员,并且我们有7个线程.所以输出应该是77777777 ......(2000 Sevens)

但有时当我运行exe时,我得到一个这样的数字:

...7777777066676672756866667777777777777377777366667777777...

为什么会这样?

(在linux上编译:g ++ -std = c ++ 11 -pthread)

1 个回答
  • 原因是"up [i] ++;" 不是线程安全的操作.它基本上是这样的:

      读取值[i]

      在读取值中添加一个

      写入值[i]

    有两个线程会发生什么:

    Thread1 1)读取值up [i](3)

    Thread1 2)在读取值中加1(4)

    Thread1 3)写入值[i](4)

    Thread2 1)读取值[i](4)

    Thread2 2)在读取值中加1(5)

    Thread2 3)写入值[i](5)

    会发生什么:

    Thread1 1)读取值up [i](3)

    Thread2 1)读取值[i](3)

    Thread1 2)在读取值中加1(4)

    Thread1 3)写入值[i](4)

    Thread2 2)在读取值中加1(4)

    Thread2 3)写入值[i](4)

    所以两个线程都向数组写入4!

    要解决此问题,您需要对阵列执行互斥或原子增量操作:http: //baptiste-wicht.com/posts/2012/07/c11-concurrency-tutorial-part-4-atomic-type.html

    2023-01-01 18:20 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有