问题描述:

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). 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.

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).

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_ts in an array?

网友答案:

If you have multiple threads reading and writing to the mutex_array, you will need another mutex to guard it.

Are you sure you will have multiple threads writing to the mutex_array?

The other thing is, instead of having two maps, you can have a 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.

网友答案:

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.

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? pthread_mutex_t and std::mutex aren't. 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. (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; 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.

相关阅读:
Top