【发布时间】:2018-08-29 02:48:14
【问题描述】:
`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),它使我们不使用任何休眠/yeilding 调用。
【问题讨论】:
-
考虑使用
std::mutex来保护地图免受并发访问 -
volatile会出现什么样的编译器错误? -
volatile不像现在你认为的那样。大多数编译器都会忽略该关键字,并且它不会使任何线程更安全。您寻求的模式是您想要一个 std::condition_variable 以及一个锁/互斥锁来保护对my_map的访问。但奇怪的是my_map的所属类是如何在其他线程仍然引用其内部成员的情况下设法破坏的——这听起来像是一个设计问题。您是否考虑过将 std::shared_ptr 用于地图实例?正如上面其他人所建议的那样,您需要一个围绕 my_map 访问的互斥锁。 -
打败我。我唯一要添加的是指向What is the XY Problem? 的链接。
-
volatileNOT 是否意味着原子!您不能将它用于线程同步。使用std::atomic或锁。
标签: c++ multithreading asynchronous volatile unordered-map