这听起来可能是假的,但我有点困惑,我已经看过这个问题,当我们在相同的情况下,我必须使我的map
成为静态的,所以对于将在单独的threads
中创建的所有实例来说,它都是常见的,并且我想同步将在我的地图上工作的函数,所以我想在我的类中创建一个std::mutex
作为static
,就像在给定的链接中所建议的答案一样。在这种情况下,在获取和锁定mutex
本身时会出现任何竞争条件吗?是否有更好的方法可以使用static map
来同步mutex
上的函数?
发布于 2016-08-09 21:24:27
是否将
std::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
发布于 2016-08-09 21:47:50
No.
Mutexe(和其他同步原语)是使用操作系统的支持来实现的。只有这样他们才能做好自己的工作。
他们执行这项工作的能力的一个直接推论是,他们自己不容易受到种族条件的影响--对互斥体的锁定和解锁操作是原子的。
否则,它们就没有多大用处了!每次你使用互斥,你必须用另一个互斥保护它,然后用另一个互斥保护这个互斥,以此类推,直到你有了无限数量的互斥,它们实际上都没有实现任何有用的东西。:)
具有静态存储持续时间的std::mutex
对象不会以任何方式改变这一点。您可能在考虑函数-static
变量(假设它们还不对竞争条件免疫,则必须进行同步,因为它们可能被不同的线程并发访问;但是,理想情况下,您根本不会使用它们,因为它们使函数不能重新进入)。
https://stackoverflow.com/questions/38860572
复制相似问题