我需要换出std :: map来更新一些配置。这发生在一个线程中。
在另一个线程中,我需要读取该映射的值(现在只有一个消费者线程)。
在生产者线程中,我目前有(伪代码):
pthread_mutex lock;
std::map<int, char> current_config;
std::map<int, char> new_config;
...
<Read into new config>
ScopeLock(lock);
current_config.swap(new_config);
在消费者线程中,我在生产者线程中调用了一个访问器,它执行以下操作:
ScopeLock(lock)
return current_config;
这似乎会阻止消费者在交换期间访问地图,但我想知道如果消费者使用地图会发生什么,然后生产者需要交换地图。
这个线程安全吗?
我想我可以在两个线程中锁定,但我试图避免要求消费者使用锁。
答案 0 :(得分:0)
如果您的访问者通过引用返回,则代码不安全,因为使用者获取引用,锁被释放,但您的生产者可能会进行另一次交换。
如果访问者按值返回,那么您的代码可能是安全的,因为您设置了锁并返回一个副本,然后删除了锁。
我说“可能”因为你的保护是不够的:我认为你的制作人不仅交换了地图,而且还在初始化,填充和更新地图。因此,您需要为每个生成器函数设置锁定,以便以任何方式修改地图。另外,您的消费者可以阅读地图,认为这是安全的,而其他代码则会改变现有的地方。
此外,使用副本意味着您的消费者可以使用过时的数据,使得处理不尽可能地并发。
另一种选择可能是生产者和消费者使用共享地图,该地图嵌入在一个对象中,该对象旨在嵌入生产者和消费者对地图的线程安全访问。