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;
};