Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我是否可以将一个对象传递给另一个进程,只传递它的';指向共享内存的指针?_C++_Ipc_Shared Memory - Fatal编程技术网

C++ 我是否可以将一个对象传递给另一个进程,只传递它的';指向共享内存的指针?

C++ 我是否可以将一个对象传递给另一个进程,只传递它的';指向共享内存的指针?,c++,ipc,shared-memory,C++,Ipc,Shared Memory,我有一个非常复杂的类(里面有无序的映射等等),我想在我的两个进程中与它共享一个对象。我能简单地将一个指针从一个进程传递到另一个进程吗?我想没有,但希望听到“是的!” 如果“否”,我将非常感激看到如何应对这种情况的任何链接。 对于所有进程,我只需要此对象的一个实例,因为它非常大,所有进程都将以只读方式与它一起工作。否,进程(自然)不共享内存。如果boost是一个选项,那么您可以查看一下是否可以轻松共享内存。否,指针对其他进程没有意义。操作系统为其他进程创建单独的地址空间;默认情况下,他们不知道其他

我有一个非常复杂的类(里面有无序的映射等等),我想在我的两个进程中与它共享一个对象。我能简单地将一个指针从一个进程传递到另一个进程吗?我想没有,但希望听到“是的!”

如果“否”,我将非常感激看到如何应对这种情况的任何链接。
对于所有进程,我只需要此对象的一个实例,因为它非常大,所有进程都将以只读方式与它一起工作。

否,进程(自然)不共享内存。如果boost是一个选项,那么您可以查看一下是否可以轻松共享内存。

否,指针对其他进程没有意义。操作系统为其他进程创建单独的地址空间;默认情况下,他们不知道其他进程正在运行,甚至不知道这样的事情是可能的。

这里的诀窍是,内存必须以相同的方式在两个进程中映射。如果您的映射共享内存可以这样安排,它将工作,但我打赌这将是非常困难的

还有一些其他的可能性。第一种是使用数组;数组索引将在这两个进程中工作


您还可以使用来确保在共享内存中的已知位置分配对象,并使用这些偏移量。

如果您在linux上,您可以使用共享内存来存储进程之间的公共数据。对于一般情况,请查看BoostIPC库


但是,一个进程的指针不能用于另一个进程(如果访问IO或某些特殊设备,可以使用它的地址)

如果使用Qt4,则可以使用套接字和自定义序列化协议。

您当然可以使用IPC来实现这一点,在很多情况下,多进程比多线程进程更有意义(至少有一个进程是基于遗留代码构建的,您无法对其进行大量修改,它们最好用不同的语言编写,您需要将一个进程中影响其他进程稳定性的故障机会降至最低,等等)在与POSIX兼容的环境中,您可以这样做

int descriptor = shm_open("/unique_name_here", O_RDWR | O_CREAT, 0777);

if (descriptor < 0) {
    /* handle error */
} else {

    ftruncate(descriptor, sizeof(Object));
    void *ptr = mmap(NULL, sizeof(Object), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, descriptor, 0);

    if (!ptr || ptr == MAP_FAILED)
        /* handle error */ ;

    Object *obj = new (ptr) Object(arguments);
}
int descriptor=shm_open(“/unique_name_here”,O_RDWR | O_CREAT,0777);
if(描述符<0){
/*处理错误*/
}否则{
ftruncate(描述符,sizeof(对象));
void*ptr=mmap(NULL,sizeof(Object),PROT_READ | PROT_WRITE | PROT_EXEC,MAP_SHARED,描述符,0);
如果(!ptr | | ptr==MAP_失败)
/*处理错误*/;
Object*obj=新(ptr)对象(参数);
}
在一个过程中,然后

int descriptor = shm_open("/the_same_name_here", O_RDWR | O_CREAT, 0777);

if (descriptor < 0) {
    /* handle error */
} else {

  Object *obj = (Object *) mmap(NULL, sizeof(Object), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, descriptor, 0);

  if (!obj || obj == MAP_FAILED)
      /* handle error */ ;
}
int descriptor=shm_open(“/the_same_name_here”,O_RDWR | O_CREAT,0777);
if(描述符<0){
/*处理错误*/
}否则{
Object*obj=(Object*)mmap(NULL,sizeof(Object),PROT_READ | PROT_WRITE | PROT_EXEC,MAP_SHARED,描述符,0);
如果(!obj | | obj==MAP_失败)
/*处理错误*/;
}
另一方面,还有更多的选项,我没有在您完成清理时显示清理代码,因此您仍然应该阅读shm_open()和mmap()手册页,但这应该可以让您开始。需要记住的几点:

  • /需要共享对象使用的所有/全部内存。例如,如果对象包含指向其他对象的指针或引用,或动态分配的成员(包括容器、std::string等),则必须使用placement new来创建所有内容(或者至少是需要与其他进程共享的所有内容)在共享内存blob中。每个对象不需要新的shm_open(),但必须(在创建过程中)进行跟踪它们的大小和偏移量,在非常重要的情况下很容易出错,如果您有像STL容器这样的奇特的自动分配类型,则绝对会出错

  • 如果任何进程在共享对象后将修改该对象,则需要提供单独的同步机制。这并不比在多线程程序中所做的更糟糕,但您必须考虑这一点

  • 如果“客户端”进程不需要修改共享对象,则应使用O_RDONLY而不是O_RDWR打开它们的句柄,并在不使用PROT_WRITE权限标志的情况下调用mmap()。如果客户端进程可能进行不需要与其他进程共享的本地修改,请调用mmap()使用MAP_PRIVATE而不是MAP_SHARED。这将大大减少所需的同步量和出错的风险

  • 如果这些进程将在多用户系统上运行,并且/或者共享数据可能是敏感的和/或者这是一个高可用性应用程序,那么您将需要比上面所示更复杂的访问控制。共享内存是安全漏洞的常见来源


这是一个我已经准备好的答案,但希望能有一些诀窍:(@如果你能控制这些进程,为什么不将它们转换为线程?共享内存比共享内存更容易。似乎更明智,因为它们都将初始化其内部数据结构的知识(你共享的对象)是的,我想我会这样做。我问这个问题是为了确保我没有简单的IPC解决方案。如果我用placement new运算符构造一个对象,它会用相同的运算符自动构造其成员吗?非指针成员当然会在分配给父对象的空间内构造。如果你的类构造函数rs或其他方法使用new为其他对象分配空间,该内存将/不/位于共享blob内。如第一个项目符号中所述,这可能是复杂性和错误的主要来源。如果共享对象太复杂,无法手动避免此行为,则可以考虑定义自定义新运算符,在共享blob内进行分配设置特定全局标志时的blob。