I believe the basic understanding of Boost.Interprocess is correct, but the implementation is wrong. In this case, process 2:
- Constructs a local copy of
IDAInterface
from the sharedIDAInterface
instance. Changes to the local copy will not be observed by other processes. - Modifies the wrong member variable. Process 1 is checking
myValue
, but Process 2 modifiesEineZahl
.
Another point to note is it that when using segment_manager::find()
, the return value's first
member variable should be checked for non-null to determine if the instance was found. In the case where the instance was not found, the second
member variable will be 1
.
Here is a complete example where Process 1 creates an integer in a shared memory segment, setting the value to 15. Process 1 will then spawn Process 2, who will attach to the shared memory segment, locate the integer, and change its value to 10. Once Process 2 exits, Process 1 prints the modified value.
#include <cstdlib>
#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
const char* segment_name = "MySharedMemory";
const char* instance_name = "MyType instance";
typedef int my_type;
int parent_main(const std::string& process)
{
using namespace boost::interprocess;
struct shm_remove {
shm_remove() { shared_memory_object::remove(segment_name); }
~shm_remove(){ shared_memory_object::remove(segment_name); }
} remover;
// Create memory segment.
managed_shared_memory segment(create_only, segment_name, 65536);
// Create an instance of my_type with a value of 15 in the shared segment.
my_type* instance = segment.construct<my_type>(instance_name)(15);
// Print value before child.
std::cout << "p1 - before child: " << *instance << std::endl;
// Spawn child.
std::string command = process + " child";
if (0 != std::system(command.c_str())) return 1;
// Child has exited, so print the shared instance value.
std::cout << "p1 - after child: " << *instance << std::endl;
return 0;
}
int child_main()
{
using namespace boost::interprocess;
// Attach to shared memory segment.
managed_shared_memory segment(open_only, segment_name);
// Find the my_type instance in the segment.
my_type* instance = segment.find<my_type>(instance_name).first;
// If the instance was not found, then return early.
if (!instance) return 1;
// Value before modifying (initial value set by parent).
std::cout << "p2 - begin child: " << *instance << std::endl;
// Modify and print value.
*instance = 10;
std::cout << "p2 - end child: " << *instance << std::endl;
return 0;
}
int main(int argc, char *argv[])
{
return (1 == argc) ? parent_main(argv[0]) : child_main();
}
Output:
p1 - before child: 15
p2 - begin child: 15
p2 - end child: 10
p1 - after child: 10