[英]How to make an object in c++ volatile?
`struct MyClass {
~MyClass() {
// Asynchronously invoke deletion (erase) of entries from my_map;
// Different entries are deleted in different threads.
// Need to spin as 'this' object is shared among threads and
// destruction of the object will result in seg faults.
while(my_map.size() > 0); // This spins for ever due to complier optimization.
}
unordered_map<key, value> my_map;
};`
我有上面的类,其中无序映射的元素在析构函数中被异步删除,并且我必须旋转/睡眠,因为该对象在其他线程之间共享。 我无法将my_map
声明为volatile
因为它会导致编译错误。 我还能在这里做什么? 我如何告诉编译器my_map.size()
在某个时间点将为0。 请不要告诉我为什么/这种设计不好。 由于无法解释的原因,我无法更改设计,除非我在此处编写了数千行代码。
编辑:使用自旋锁的版本保护my_map
。 因此,线程在擦除条目之前确实会抓住自旋锁。 只是while(my_map.size() > 0);
是我在代码中唯一的“天真”旋转。 我将其转换为抓取自旋锁,然后(循环查看)大小并正常工作。 尽管使用condition_variable
是正确的方法,但我们使用异步编程模型(例如SEDA),该模型将我们绑定为不使用任何休眠/后退调用。
volatile
不是解决此问题的方法。 volatile
具有三种用途:1.访问驱动程序中的内存映射设备; 2.信号处理程序; 3. setjmp用法。
阅读下面的,一遍又一遍,直到它下沉。 volatile
是在多线程没用。
像这样的天真自旋锁有三个问题:
A
可能会检查锁变量,发现资源可访问,但是在设置锁变量之前先被抢占。 随之而来的是线程B
,该线程B
也找到了显示资源可访问的锁变量,因此它对其进行锁定并开始访问该资源,然后线程A
唤醒并再次锁定该变量,并访问该资源。 volatile
仅解决了第一个问题,对解决另外两个问题无济于事。 需要注意的是,即使标准不要求,默认情况下,x86 / x64上的MSVC也会在volatile
访问中添加内存屏障。 碰巧解决了第三个问题,但仍然不能解决第二个问题。
解决所有这三个问题的唯一方法是使用正确的同步原语: std::atomic<>
如果您确实必须旋转锁),最好是std::mutex
,也许还需要std::condition_variable
来获得使线程进入睡眠std::condition_variable
的锁直到发生一些有趣的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.