简体   繁体   中英

Is Shared memory crash safe?

I want to share data between two or more processes in very efficient manner. I'm using C++ and boost.Interprocess. Here are the processes:

  • Process A: Creates shared memory and write to it afterwards.
  • Process B: Reader that reads from shared memory
  • Process C: same as process B

Constraints: Size of the shared memory is not known in advance, it could be 10kB or 30 MB. Process A and B could be started independently so process B could be started before process A. I would like as much as possible to be crash safe, which means that in case of reader process crash, the application continues...

Code currently used in SharedMem (using managed segment so far):

struct MainStruct
{
    MainStruct(const void_allocator& void_alloc)
        :/* ... */
    {
    }
    //Mutex to protect access to the data
    mutex_type          mutex;

    //Condition to wait when new data is ready
    condition_type      cond_new_data;

    //Condition to wait when data has been read by a reader
    condition_type      cond_data_read;

    // More code ...
};

// Shared memory creation
m_sho = new bi::managed_shared_memory(bi::create_only, m_shared_memory_name.str(), size);
void_allocator alloc_inst(m_sho->get_segment_manager());
m_main_struct = m_sho->construct<MainStruct>("main")(alloc_inst);
m_data_struct = m_sho->construct<CharVector>("data")(alloc_inst);

My questions:

  • If a process using shared memory crashes, is it possible to assume everything is fine and continue? A mutex could be locked, but it is possible to detect it thanks to a time_locked() and then force unlock the mutex. Does it make sense to try fixing the memory? Or is it gambling and I should unmap and remap it?
  • Knowing the constraints of my project (unknown size at start, crash proof...), do you have any design in mind that you would recommend (using Boost.Interprocess if possible)

Thanks.

Request to the OS a segment to share and don't run any process until the program gets a valid one. Initialising the segment will allow process B to know if process A has written different values.

Unless you are absolutely sure that process B is not going to read the memory before process A has finished, synchronisation mechanisms are mandatory, and it depends on the purpose you want to achieve, two useful ones use to be (but check all of them):

  • Semaphore : Process B has to wait until Process A writes some data
  • Mutex (and associated condition ): Process B can read anytime, except at the same time than Process A is writting (because you get the resource)

Bear in mind that shared memory can throw, just catch it. The size is not a problem, truncate (with read_write) sets the size of the segment:

When a shared memory object is created, its size is 0. To set the size of the shared memory, the user must use the truncate function call, in a shared memory that has been opened with read-write attributes

Or use the constructor with windows_shared_memory .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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