1

我想了解以下代码的行为。

IDAInterface 是一个具有成员“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;
} 

输出:

过程 2 15

过程 2 10

项目 1 15

项目 1 15

据我了解应该是进程1中的值,在运行进程2之后,也是10。为什么进程1中“myValue”的值总是15?以及如何在流程1中通过流程2获取“myValue”的修改值?

4

1 回答 1

0

相信对Boost.Interprocess的基本理解是正确的,但实现是错误的。在这种情况下,过程 2:

  • IDAInterface从共享IDAInterface实例构造一个本地副本。其他进程不会观察到对本地副本的更改。
  • 修改了错误的成员变量。进程 1 正在检查myValue,但进程 2 修改EineZahl

还有一点需要注意的是,在使用的时候,应该检查segment_manager::find()返回值的成员变量是否为非空,以确定是否找到了实例。first在未找到实例的情况下,second成员变量将为1.


这是一个完整的示例,其中进程 1 在共享内存段中创建一个整数,将值设置为 15。然后进程 1 将生成进程 2,该进程将附加到共享内存段,定位整数,并将其值更改为 10 . 一旦进程 2 退出,进程 1 打印修改后的值。

#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();
}

输出:

p1 - before child: 15
p2 - begin child: 15
p2 - end child: 10
p1 - after child: 10
于 2013-05-15T14:44:50.520 回答