Paul C
Paul C

Reputation: 8457

How can I safely clear a boost::interprocess:vector in shared memory if other processes could be iterating over it?

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

Answers (2)

Andres Gonzalez
Andres Gonzalez

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

Mike Seymour
Mike Seymour

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

Related Questions