Reputation: 8457
Let's say I have a boost interprocess vector in shared memory. One process may be iterating through it. If another process wants to concurrently clear the vector, what do I need to do so that I don't crash in the process that is doing the iteration?
PROCESS #1 - iterates over vector in shared memory
using namespace boost::interprocess;
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<int, ShmemAllocator> MyVector;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
const ShmemAllocator alloc_inst (segment.get_segment_manager());
MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);
size_t size = myvector->size();
for (size_t i = 0; i < size; i++)
{
//potential crash when PROCESS 2 calls clear
int value = myvector->at(i);
}
PROCESS #2 - can potentially clear the vector in shared memory
using namespace boost::interprocess;
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<int, ShmemAllocator> MyVector;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
const ShmemAllocator alloc_inst (segment.get_segment_manager());
MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);
if (somecondition)
myvector->clear();
Two things I was thinking: copy the vector to local memory std::vector before iterating. I'm not sure if the copy would be safe, though, either. Can't imagine it would
or
some sort of interprocess mutex, which for simplicity's sake, I'd like to avoid.
Upvotes: 1
Views: 598
Reputation: 2239
By definition, a shared memory segment can be accessed by multiple writers/readers. Consequently, you MUST protect the data and serialize all access to the segment. I do not think you can avoid using some sort of mutex. The way I have done this, is to defined a header struct at the top of the segment and have all shared data start after that struct. In that struct you can put any house-keeping elements like flags, etc. But the most important is to put a mutex at the top of the struct. Then the write/read access routines acquire the mutex first before writing or reading the data.
Upvotes: 1
Reputation: 254451
If you're concurrently modifying and accessing it, then you'll need a mutex or equivalent.
Copying (or moving) it, then iterating over the non-shared copy might be sensible, if the iteration is slow - you'll only need to lock the mutex for the copy/move, not the iteration. But you'll still need to guard all accesses to the shared object with a mutex.
Upvotes: 1