C++11:在多线程程序中使用局部静态变量导致 coredump

Posted

技术标签:

【中文标题】C++11:在多线程程序中使用局部静态变量导致 coredump【英文标题】:C++11 : Using local static variables in multithreaded program caused coredump 【发布时间】:2021-12-28 06:55:49 【问题描述】:

在C++11中,我创建了100个线程,每个线程调用Test::PushFunc,添加局部静态变量index,插入到局部集合变量本地地图

理论上,index存储在Initialized Data Segment Memory中,并在程序运行时由每个线程添加。 下面一行

assert(it == localMap.end());

是合理的,因为 index 插入到 localMap 中不会重复。

但实际上,程序在断言中是随机转储的。你能告诉我为什么吗?谢谢。

#include <set>
#include <iostream>
#include <thread>
class Test 
public:
    std::set<std::string> localMap;
    void PushFunc()
    
        static uint64_t index = 0;
        while (true) 
            std::cout << "index : " << index << "\n";
            ++index;
            const auto& s = std::to_string(index);
            const auto& it = localMap.find(s);
            assert(it == localMap.end()); //! coredump here
            localMap.insert(s);
            if (index > 20000000) 
                break;
            
        
    
;


int main ()

    std::vector<std::thread> processThreads;
    for (int i = 0; i < 100; ++i) 
        processThreads.emplace_back(
                std::thread([]()
                
                    Test t;
                    t.PushFunc();
                
                ));
    
    for(auto& thread : processThreads)
        thread.join();
    

【问题讨论】:

为什么是const auto&amp; @ÖöTiib localMap 不在线程之间共享,只有 index 是。 为什么不能const auto&amp;?每个变量都不会改变可以定义为const 【参考方案1】:

但实际上,程序在断言中是随机转储的。你能告诉我为什么吗?

因为你有一个数据竞争——多个线程试图在没有任何同步的情况下读取和写入同一个变量。

index 是一个全局 变量。您需要使用互斥锁来保护对它的访问。

日期:

但localMap不是全局变量,数据竞争无法解释一个索引重复两次。

    具有数据竞争(未定义行为)的程序可以产生任何结果。 是的,可以。

考虑以下指令交错(时间递减):

T1 将index 加载到寄存器中(比如5)。 T2 加载index(再次5) T1 将 index 递增到 6,将 "6" 存储到其映射中 T1 加载 6,将 index 递增到 7,将 "7" 存储到其映射中 T2“增量”索引到6,将"6" 存储到自己的地图中 T1 加载 6,将其增加到 7,尝试将 "7" 存储到其映射中 ==> 断言失败!

问题在于index++ 不是原子 操作,并且(没有互斥体)其他线程可能会干扰它。

【讨论】:

但是localMap不是全局变量,数据竞争无法解释一个index重复两次。 @ArmStrong 你错了。我已经更新了答案。 @ArmStrong 您正在通过++index 在多个线程中更新index。一个线程可以多次观察到相同的值(最多2500次)。 @EmployedRussian 非常感谢。你的解释很清楚。

以上是关于C++11:在多线程程序中使用局部静态变量导致 coredump的主要内容,如果未能解决你的问题,请参考以下文章

C++11中的局部静态变量初始化线程安全吗? [复制]

java 局部静态变量在多线程环境下是不是有线程安全问题??

C++0x 和静态局部变量的性能损失?

别翻了,成员变量和局部变量在多线程中的使用,看这篇就够了

别翻了,成员变量和局部变量在多线程中的使用,看这篇就够了

别翻了,成员变量和局部变量在多线程中的使用,看这篇就够了