boost:interprocess > managed_shared_memory > different values -
i understand behavior of following code.
idainterface libary member "myvalue".
c++:
#include <boost/interprocess/managed_shared_memory.hpp> #include <cstdlib> #include <idainterface.h> idainterface ifida; int main(int argc, char *argv[]) { using namespace boost::interprocess; typedef std::pair<idainterface, int> mytype; // [1] if(argc == 1){ //parent process struct shm_remove{ shm_remove() { shared_memory_object::remove("mysharedmemory"); } ~shm_remove(){ shared_memory_object::remove("mysharedmemory"); } } remover; ifida.myvalue = 15; managed_shared_memory segment(create_only, "mysharedmemory", 65536); mytype *instance = segment.construct<mytype> ("mytype instance") (ifida, 0); std::string s(argv[0]); s += " child "; if(0 != std::system(s.c_str())) return 1; std::cout<<"\nprozess 1 "<< ifida.myvalue; std::cout.flush(); //std::cout<<"\nprozess 1 "<< instance->first.myvalue; //std::cout.flush(); //segment.destroy<mytype>("mytype instance"); if(segment.find<mytype>("mytype instance").first) return 1; } else{ managed_shared_memory segment(open_only, "mysharedmemory"); std::pair<mytype*, managed_shared_memory::size_type> res; res = segment.find<mytype> ("mytype instance"); if(res.second != 1) return 1; idainterface nifida; nifida = res.first->first; std::cout<<"\nprozess 2 "<< nifida.myvalue; std::cout.flush(); nifida.einezahl = 10; std::cout<<"\nprozess 2 "<< nifida.myvalue; std::cout.flush(); segment.destroy<mytype>("mytype instance"); } return 0; } the output:
prozess 2 15
prozess 2 10
prozess 1 15
prozess 1 15
as understood should value in process 1, after running process 2, 10. why in process 1 value of "myvalue" 15? , how modified value of "myvalue" through process 2 in process 1?
i believe basic understanding of boost.interprocess correct, implementation wrong. in case, process 2:
- constructs local copy of
idainterfacesharedidainterfaceinstance. changes local copy not observed other processes. - modifies wrong member variable. process 1 checking
myvalue, process 2 modifieseinezahl.
another point note when using segment_manager::find(), return value's first member variable should checked non-null determine if instance found. in case instance not found, second member variable 1.
here complete example process 1 creates integer in shared memory segment, setting value 15. process 1 spawn process 2, attach shared memory segment, locate integer, , change value 10. once process 2 exits, process 1 prints 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 instance of my_type value of 15 in 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, print shared instance value. std::cout << "p1 - after child: " << *instance << std::endl; return 0; } int child_main() { using namespace boost::interprocess; // attach shared memory segment. managed_shared_memory segment(open_only, segment_name); // find my_type instance in segment. my_type* instance = segment.find<my_type>(instance_name).first; // if instance not found, return early. if (!instance) return 1; // value before modifying (initial value set parent). std::cout << "p2 - begin child: " << *instance << std::endl; // modify , 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
Comments
Post a Comment