0

I am attempting to use Boost::Interprocess to (i) create a set in shared memory in one process, and (ii) print the values of the set (1,2,3) in another process.

This program compiles, but crashes:

#include "stdafx.h"
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/set.hpp>
#include <functional>
#include <utility>
#include <set>

using namespace boost::interprocess;

//Define allocator type
typedef allocator<int, managed_shared_memory::segment_manager> shmAlloc;

//Define set type
typedef set<int,std::less<int>,shmAlloc> mySet;

//Write function
void writer()
{
    //Remove shared memory on construction and destruction
    struct shm_remove
{
    shm_remove() { shared_memory_object::remove("MySharedMemory"); }
    ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
} remover;

//Create shared memory object
managed_shared_memory segment(create_only, "MySharedMemory", 65536);

//Initialize the shared memory STL-compatible allocator
shmAlloc alloc_inst(segment.get_segment_manager());

//Construct the set
mySet *myset =
    segment.construct<mySet>("MySet")(std::less<int>(),alloc_inst);

//Insert data
myset->insert(3);
myset->insert(1);
myset->insert(2);

}

//Read-and-print function
void reader(){

//Open shared memory object
managed_shared_memory segment(open_only, "MySharedMemory");


//Find the set
mySet *myset = segment.find<mySet>("MySet").first;

//Print set members
for (auto it = myset->begin(); it != myset->end(); ++it)
    std::cout << *it;

std::cout << std::endl;

}

int main(){

writer();
reader();

std::cout << "Press any key to continue" << std::endl;
std::cin.ignore();
return 0;
}

I am able to write-and-print if I throw everything into the writer() function, so I know the problem has something to do with synchronization. I need to do this with 2 processes.

Thanks for your help.

1 Answers1

1

Adding boost::interprocess::interprocess_exception exception handling into reader() reveals:

The system cannot find the file specified.

The remover objects removes shared memory file at the end of the writer() scope. If you move reader() and writer() into (as you are planning) their own processes the code will work, just you need to ensure that the writer process starts first and has got enough time to create and populate shared memory file and ends last (must be running when the reader process is running).

Alternatively you can replace shm_remove struct with single call to shared_memory_object::remove("MySharedMemory"); at writer construction, then your current example with work with no problem. In 2 processes scenario you will not need to keep writer running for the whole time when you need to use reader. Keep in mind that the shared memory file will not be removed at writer destruction and will stay all the time which may not be fine if the file is big.

doqtor
  • 8,414
  • 2
  • 20
  • 36