将std::mutex设为static会为互斥对象本身创建竞争条件

Does Making std::mutex as static creates race-condition for the mutex itself

本文关键字:对象 竞争 条件 创建 mutex std 设为 static      更新时间:2023-10-16

这听起来可能很假,但我有点困惑,我已经经历了这个问题,当我们研究它时,在相同的情况下,我必须将我的map设置为静态,这样它将对将在单独的threads中创建的所有实例都是通用的,我想同步将在我的映射上运行的函数,所以我想在课堂上把std::mutex作为static,就像在给定的链接中建议的答案一样。。在这种情况下,是否会出现获取和锁定mutex本身的竞争条件?有没有更好的方法可以使用mutex 同步static map上的功能

std::mutex设为静态是否会为互斥体创建竞争条件自身

不,Mutex不容易受到种族条件的影响。至于将其初始化为static,则是安全的。

$6.7:4:具有静态存储持续时间([basic.stc.static](或线程存储的块作用域变量的动态初始化持续时间([basic.stc.thread](被执行第一时间控制通过其声明;考虑这样一个变量在其初始化完成时初始化。如果初始化通过抛出异常退出,初始化为未完成,因此下次控件进入时将重试声明。如果控件同时进入声明,而变量正在初始化,并发执行将等待用于完成初始化


你说:

我想让std::mutex在我的课堂上像以前一样是静态的建议作为给定链接中的答案。

如果您还试图保护static类成员变量,请执行此操作。否则,使其成为mutable成员。事实上,您说map将被全局初始化为static是可以的,因为互斥体作为一个成员变量,将遵循套件。

class Map{
public:
    Map(...){}
    std::size_t size() const{
         std::lock_guard<std::mutex> lck(m_m);
         return m_size;
     }
     iterator add(....) {
         std::lock_guard<std::mutex> lck(m_m);
         ....
         return your_iterator;
     }
     ...etc
private:
    mutable std::mutex m_m; //FREE ADVICE: Use a std::recursive_mutex instead
    ...others
};

现在:

//Somewhere at global scope:
Map mp(... ...);
// NOTES
// 1. `mp` will be initialized in a thread safe way by the runtime. 
// 2. Since you've protected all Read or Write member functions of the class `Map`,
//    you are safe to call it from any function and from any thread

互斥(和其他同步原语(是使用操作系统的支持来实现的。这是他们完成工作的唯一途径。

他们能够胜任这项工作的一个直接原因是,他们自己不容易受到种族条件的影响;互斥对象上的锁定和解锁操作是原子操作。

否则,它们就没有多大用处!每次使用互斥体时,都必须用另一个互斥体保护它,然后用另一种互斥体保护这个互斥体,以此类推,直到你有了无限数量的互斥体,但它们都没有真正实现任何用途。:(

具有静态存储持续时间的std::mutex对象不会以任何方式改变这一点。假设您考虑的是函数-static变量(假设它们还不能免受竞争条件的影响,则必须同步,因为它们可能由不同的线程同时访问;但理想情况下,您根本不会使用它们,因为它们使函数不能重新进入(。