我想了解以下代码的行为。
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;
}
输出:
PROZESS 2 15
PROZESS 2 10
PROZESS 1 15
PROZESS 1 15
据我所知,应该是流程1中的值,在运行流程2之后,也是10。 为什么在进程1中“myValue”的值总是为15? 如何在流程1中通过流程2获取“myValue”的修改值?
答案 0 :(得分:0)
我相信对Boost.Interprocess的基本理解是正确的,但实现是错误的。在这种情况下,流程2:
IDAInterface
实例构造IDAInterface
的本地副本。其他进程将不会观察到对本地副本的更改。myValue
,但流程2会修改EineZahl
。需要注意的另一点是,在使用segment_manager::find()
时,应检查返回值的first
成员变量是否为非null,以确定是否找到了实例。如果未找到实例,second
成员变量将为1
。
这是一个完整的示例,其中进程1在共享内存段中创建一个整数,将值设置为15.然后,进程1将生成进程2,进程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