简体   繁体   English

'std :: map`中的`pthread_mutex_t`,`sem_t`

[英]`pthread_mutex_t`, `sem_t` in a `std::map`

Basically I'm maintaining a set of states for a bunch of objects: 基本上我是为一堆对象维护一组状态:

#define SUBSCRIPTION_TYPE int
std::map< SUBSCRIPTION_TYPE , bool > is_object_valid;

And I need to protect each element in is_object_valid with their respective mutex_t (Rather than a big lock). 我需要用各自的mutex_t保护is_object_valid 每个元素 (而不是大锁)。 As valid values of SUBSCRIPTION_TYPE are sparse (say, dozens of values ranging from 0 to 10000000 ), a std::map is prefered over std::vector , C-style array, etc. 由于SUBSCRIPTION_TYPE有效值是稀疏的 (例如,从0到10000000的数十个值), std::map优先于std::vector ,C样式数组等。

I'm trying to achieve something like: 我正在努力实现以下目标:

std::map< SUBSCRIPTION_TYPE , pthread_mutex_t > mutex_array;

But it doesn't seem to work. 但它似乎没有用。 (Well, data race may occur when std::map is being updated). (好吧,正在更新std::map时可能会发生数据争用)。

So what's the best way to achieve this? 那么实现这一目标的最佳方法是什么? Must I write a thread-safe subscription allocator that maps SUBSCRIPTION_TYPE into consecutive integers so that I can store the mutex_t s in an array? 我必须编写一个线程安全的订阅分配器,将SUBSCRIPTION_TYPE映射到连续的整数,以便我可以将mutex_t存储在一个数组中吗?

If any thread is modifying the map itself (inserting, etc.), you need to protect all accesses to the map. 如果任何线程正在修改地图本身(插入等),则需要保护对地图的所有访问。 After that: if the member is just a bool , how much processing can you be doing on it that adding this time to the time the map level mutex is held would change anything. 在那之后:如果成员只是一个bool ,你可以对它进行多少处理,将这个时间添加到地图级别互斥锁所持有的时间会改变任何东西。

Otherwise: if you need a mutex per object, the simple solution would be to put them into same object as the one on the map. 否则:如果你需要每个对象的互斥锁,那么简单的解决方案就是将它们放在与地图上的对象相同的对象中。 But it mutex_t copyable? 但它mutex_t复制? pthread_mutex_t and std::mutex aren't. pthread_mutex_tstd::mutex不是。 This could make the insertion code overly complex, since you can't initialize the pthread_mutex_t , or construct the std::mutex , before the object is inserted. 这可能会使插入代码过于复杂,因为在插入对象之前无法初始化pthread_mutex_t或构造std::mutex (In C++11, you could use emplace to solve this problem; contents of a map don't have to be copyable if you use emplace .) In C++03, however, you'll have to separate allocation from initialization; (在C ++ 11中,你可以使用emplace来解决这个问题;如果你使用emplace ,地图的内容就不必是可复制的。)但是,在C ++ 03中,你必须将分配与初始化分开; the struct which contains your mapped value and the mutex will in fact have to be declared with raw memory for the mutex, and then placement new used to initialize it using the iterator you get back from insert . 包含映射值的struct和互斥体实际上必须用互斥锁的原始内存声明,然后使用新的贴片来使用从insert返回的迭代器来初始化它。

If you have multiple threads reading and writing to the mutex_array , you will need another mutex to guard it. 如果您有多个线程读取和写入mutex_array ,您将需要另一个互斥锁来保护它。

Are you sure you will have multiple threads writing to the mutex_array ? 你确定你会有多个线程写入mutex_array吗?

The other thing is, instead of having two maps, you can have a map<subscription_type, object_struct> 另一件事是,您可以拥有一个map<subscription_type, object_struct> ,而不是拥有两个映射

struct object_struct {
   bool valid;
   pthread_mutex_t mutex;
};

And then have a single overarcing mutex to guard that map. 然后有一个单独的互斥锁来保护该地图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM