C++ `pthread_mutex_t`,`std::map中的`sem_t``
基本上,我为一组对象维护一组状态:C++ `pthread_mutex_t`,`std::map中的`sem_t``,c++,concurrency,stl,pthreads,C++,Concurrency,Stl,Pthreads,基本上,我为一组对象维护一组状态: #define SUBSCRIPTION_TYPE int std::map< SUBSCRIPTION_TYPE , bool > is_object_valid; 但它似乎不起作用。(嗯,当更新std::map时可能会发生数据竞争) 那么,实现这一目标的最佳方式是什么?我必须编写一个线程安全的订阅分配器,将subscription\u TYPE映射为连续整数,以便将mutex\u t存储在一个数组中吗?如果有多个线程读写mutex\u数组,则
#define SUBSCRIPTION_TYPE int
std::map< SUBSCRIPTION_TYPE , bool > is_object_valid;
但它似乎不起作用。(嗯,当更新std::map
时可能会发生数据竞争)
那么,实现这一目标的最佳方式是什么?我必须编写一个线程安全的订阅分配器,将
subscription\u TYPE
映射为连续整数,以便将mutex\u t
存储在一个数组中吗?如果有多个线程读写mutex\u数组
,则需要另一个mutex来保护它
您确定将有多个线程写入互斥体数组
另一件事是,您可以使用map
然后使用一个过遍历互斥锁来保护该映射。如果任何线程正在修改映射本身(插入等),您可以 需要保护对地图的所有访问。之后:如果 成员只是一个
bool
,您可以对其进行多少处理
将此时间添加到保持映射级别互斥体的时间中是非常重要的
会改变一切
否则:如果每个对象都需要互斥,那么简单的解决方案
就是把它们放在和地图上一样的物体里。
但是它是可复制的吗pthread\u mutex\u t
和std::mutex
不是。这可能会使插入代码过于复杂,
因为您不能初始化pthread\u mutex\u t
,或者构造
插入对象之前的std::mutex
。(在C++11中,您可以
可以使用emplace
解决此问题;地图的内容
如果在C++03中使用emplace
),则不必具有可复制性,
但是,您必须将分配与初始化分开;
包含映射值和互斥量的结构将
实际上,必须为互斥对象声明原始内存,并且
然后使用所需的迭代器来初始化它
从插入返回
地图范围锁有什么问题?@zch-Eh,效率不够。程序的一部分依赖于远程过程调用,因此不必要地阻塞多个线程代价太高。您没有显示足够的代码来进行真正的诊断,但我有一些猜测:当您在映射中“插入”互斥时,实际上是在创建一个新的互斥。所以你需要初始化它并锁定它。您从中复制的互斥体现在已无用。因此,请确保您有时没有锁定原始对象,有时也没有锁定映射中的对象。@WanderingLogic他应该能够延迟初始化映射中的互斥对象,直到它实际位于映射中。类似于std::pair r=myMap.insert(make_pair(newKey,pthread_mutex_t());断言(r.second);pthread_mutex_init(&r.first->second,NULL)代码>当然,他必须在整个序列中保持映射上的全局锁。一旦有多个线程访问映射,并且至少有一个线程正在写入映射,所有线程都需要保护访问。当然,他也不能调用互斥体上的pthread\u mutex\u init
,直到它在映射中实际就位。(至少根据Posix,如果互斥体是使用默认值初始化的,我发现很难相信总是复制pthread\u mutex\u t initializer=pthread\u mutex\u initializer;
是行不通的,只要你在插入之前不尝试使用它。
std::map< SUBSCRIPTION_TYPE , pthread_mutex_t > mutex_array;
struct object_struct {
bool valid;
pthread_mutex_t mutex;
};