2

I am trying to use the c++ boost library to create a hashmap in a (boost) shared memory location. So far so good, this is all nicely documented in the boost documentation. However, I want to have a mutex lock on the map I create but I cannot understand whether this is already part of the hashmap container.

I cannot find this information in the documentation and trying to read through the boost sources I quickly got lost, even google does not provide the answer. Of course it would be easy to implement a mutex lock using the boost library but I don't want to end up with a redundant locking mechanism.

If anyone could tell me whether the boost containers, hashmap in particular, come with locking included that would be very helpful. Bonus points if you can point me to the place on the www where I could have found this information myself.

Tom
  • 23
  • 4
  • 3
    Not familiar with boost, rather using standard containers... But if it is not described, it is pretty likely that there is no thread-safety implemented either. Having such would contradict a C++ paradigm: Only provide what really is needed; if the hash map would be used in a single threaded environment, such protection would cost performance for nothing... – Aconcagua Sep 20 '18 at 06:23
  • Side note: as you mention shared memory - have a look at [here](https://stackoverflow.com/questions/46662935/stdmutex-in-shared-memory-not-working), too. – Aconcagua Sep 20 '18 at 06:30
  • Thanks @Aconcagua. The sources of the shared memory hashmap container seem to point to the general container so it sounds like you are right. When I have finished the code I can do a little test and we will know for sure. – Tom Sep 20 '18 at 06:32
  • [Here](http://preshing.com/20160201/new-concurrent-hash-maps-for-cpp/) are mentioned some implementations of concurrent hash maps, might be useful as an alternative. Facebook Folly has [one](https://github.com/facebook/folly/blob/master/folly/concurrency/ConcurrentHashMap.h) as well, etc. – Daniel Langr Sep 20 '18 at 06:41

4 Answers4

2

The boost "containers for shared memory" are merely aliases for the general-purpose containers from Boost Container. In fact, they only become "for shared memory" when used with the appropriate allocator type(s).

As such, they do not have synchronization built in (unless documented of course).

sehe
  • 374,641
  • 47
  • 450
  • 633
1

In addition to @sehe answer, container-level locking is too fine-grained to be useful. Many operations require more than one call to container functions and these calls must be done as one atomic sequence. For example, in:

if(!container.empty()) {
    auto last = container.back();
    container.pop_back();
    // process last
}

One lock must be held during all three container calls, rather than locked and released for each call.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
1

They do not have a built in synchronisation. Last time i implemented something similar between a Writer and a Reader the procedure was: The Writer creates a shared memory segment for the SharedMutex and an other shared memory segment for the sharedVector. The Writer gets the address of the memory segment (of the SharedMutex) and stores this reference to a local mutex variable. After that it locks it and starts writing the vector in shMem. As soon as it unlocks the mutex the Reader starts reading the values.

The boost documentation described it with the following lines of code:

using namespace boost::interprocess;
shared_memory_object::remove("SharedMutex");
shared_memory_object shmObj(create_only, "SharedMutex", read_write);
shmObj.truncate(sizeof(SharedMutex));
mapped_region region(shmObj, read_write);
void * addr = region.get_address();
SharedMutex * shared_mtx = new (addr) SharedMutex;
scoped_lock<interprocess_mutex> lock(shared_mtx->mutex);
//Start Writing in the Vector shared segment, SharedMutex is boost::interprocess::mutex
LeoSar
  • 21
  • 2
0

Try with typedef for a default basic_managed_shared_memory with null mutex family of narrow characters:

typedef basic_managed_shared_memory<char, rbtree_best_fit<null_mutex_family>, iset_index> managed_shared_memory_null_mutex;

And use a robust interprocess lock outside the managed_shared_memory_null_mutex, such as system V semphore.

Thomas Blanquet
  • 507
  • 6
  • 17