C语言:如何通过IPC在父进程和子进程(分叉)之间共享结构体(或数组)?

时间:2022-11-03 17:01:15

I googled this for the past two weeks and I didn't get any answer. This is what I have:

我在谷歌上搜索了两个星期,没有得到任何答案。这就是我所拥有的:

  • A parent process, which creates a struct myStruct that is basically a linked list using pointers (if this is a major issue, I can accept to use a fixed size array instead).

    父进程,它创建一个struct myStruct,它基本上是一个使用指针的链表(如果这是一个主要问题,我可以接受使用一个固定大小的数组)。

  • A fixed number of child processes created with fork() that need a read/write access to the struct (or array) created by the parent.

    使用fork()创建的固定数量的子进程,这些进程需要对父进程创建的结构体(或数组)进行读/写访问。

I don't know how to do in order to make the variable myStruct become shared between processes.

我不知道如何让变量myStruct在进程之间共享。

I tried to solve the problem using SysV IPC functions like shmget(), shmat(), etc... in order to allocate my variable in shared memory, but I don't know how to work with void memory pointers to read/write the values into myStruct.

我尝试使用SysV IPC函数来解决这个问题,比如shmget()、shmat()等等。为了在共享内存中分配我的变量,但是我不知道如何使用void内存指针来读取/写入到myStruct中的值。

Ideally, I would like to be able to use the dot notation (myStruct.node)->attribute = value in every process without having to deal with pointers, since I don't know how my struct is organized into memory.

理想情况下,我希望能够在每个进程中使用点表示法(myStruct.node)->属性= value,而不必处理指针,因为我不知道如何将我的结构组织到内存中。

Is that possible? Could some of you please help? Any help is REALLY appreciated.

这有可能吗?你们中有人能帮忙吗?非常感谢你的帮助。

Further note: I know using threads, pipes, sockets or things like that would be much easier, but this work is for academic purposes for which I have to simulate the presence of multiple independent processes.

进一步的注意:我知道使用线程、管道、套接字或类似的东西会容易得多,但是我必须为学术目的模拟多个独立进程的存在。

2 个解决方案

#1


2  

If you create a shared anonymous mapping with:

如果您创建了一个共享的匿名映射:

p = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

Then these pages will not be copied-on-write, but rather will be shared by all forked processes.

然后这些页面不会被复制,而是被所有的分叉进程共享。

Note that you have to be careful with locking here. You can use standard pthread mutexes and condvars on the shared memory segment between processes if (and only if!) you use pthread_mutexattr_setpshared and pthread_condattr_setpshared to mark them as shared between processes.

注意,这里的锁要小心。您可以在进程间的共享内存段上使用标准的pthread互斥锁和condvars,如果(并且仅当!)您使用pthread_mutexattr_setpshared和pthread_condattr_setpshared将它们标记为进程之间的共享。

Note also that this technique maps a fixed size arena, and must be done before forking. How you manage the contents of the memory at p is up to you. It's nontrivial to create a resizable shared memory arena; if you want to go that route, I'd recommend posting a second question, as different approaches may be necessary.

还请注意,此技术映射一个固定大小的竞技场,必须在分叉之前完成。如何管理p处的内存内容由您决定。创建一个可调整大小的共享内存竞技场是非常重要的;如果你想走那条路线,我建议你提出第二个问题,因为不同的方法可能是必要的。

#2


0  

The easiest way to share memory across a fork is to use a mmap()ed region of memory. If you use an anonymous mmap() (with MAP_ANON and MAP_SHARED) to store your struct (array, whatever) instead of malloc()ed memory, it will be shared by the child process.

跨fork共享内存的最简单方法是使用内存的mmap()ed区域。如果您使用匿名的mmap()(带有MAP_ANON和MAP_SHARED)来存储结构体(数组等等)而不是malloc()ed内存,那么它将被子进程共享。

#1


2  

If you create a shared anonymous mapping with:

如果您创建了一个共享的匿名映射:

p = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

Then these pages will not be copied-on-write, but rather will be shared by all forked processes.

然后这些页面不会被复制,而是被所有的分叉进程共享。

Note that you have to be careful with locking here. You can use standard pthread mutexes and condvars on the shared memory segment between processes if (and only if!) you use pthread_mutexattr_setpshared and pthread_condattr_setpshared to mark them as shared between processes.

注意,这里的锁要小心。您可以在进程间的共享内存段上使用标准的pthread互斥锁和condvars,如果(并且仅当!)您使用pthread_mutexattr_setpshared和pthread_condattr_setpshared将它们标记为进程之间的共享。

Note also that this technique maps a fixed size arena, and must be done before forking. How you manage the contents of the memory at p is up to you. It's nontrivial to create a resizable shared memory arena; if you want to go that route, I'd recommend posting a second question, as different approaches may be necessary.

还请注意,此技术映射一个固定大小的竞技场,必须在分叉之前完成。如何管理p处的内存内容由您决定。创建一个可调整大小的共享内存竞技场是非常重要的;如果你想走那条路线,我建议你提出第二个问题,因为不同的方法可能是必要的。

#2


0  

The easiest way to share memory across a fork is to use a mmap()ed region of memory. If you use an anonymous mmap() (with MAP_ANON and MAP_SHARED) to store your struct (array, whatever) instead of malloc()ed memory, it will be shared by the child process.

跨fork共享内存的最简单方法是使用内存的mmap()ed区域。如果您使用匿名的mmap()(带有MAP_ANON和MAP_SHARED)来存储结构体(数组等等)而不是malloc()ed内存,那么它将被子进程共享。