Linux 子进程是否复制整个阵列?

Linux 子进程是否复制整个阵列?,linux,unix,process,fork,pipe,Linux,Unix,Process,Fork,Pipe,我正在编写一个基本的UNIX程序,其中涉及进程之间相互发送消息。我同步进程的想法是简单地使用一组标志来指示进程是否已达到代码中的某个点 例如,我希望所有进程都等待,直到它们都已创建。我还希望他们等到彼此发送完消息后再开始阅读管道 我知道,当进程写入以前定义的变量时,它会执行写时复制操作 我想知道的是,如果我制作了一个标志数组,指向该数组的指针会被复制,还是整个数组都会被复制(从而使我的想法毫无用处) 我还想了解有关进程间通信和进程同步的任何提示 编辑:进程正在相互写入进程的管道。每个进程将发送以

我正在编写一个基本的UNIX程序,其中涉及进程之间相互发送消息。我同步进程的想法是简单地使用一组标志来指示进程是否已达到代码中的某个点

例如,我希望所有进程都等待,直到它们都已创建。我还希望他们等到彼此发送完消息后再开始阅读管道

我知道,当进程写入以前定义的变量时,它会执行写时复制操作

我想知道的是,如果我制作了一个标志数组,指向该数组的指针会被复制,还是整个数组都会被复制(从而使我的想法毫无用处)

我还想了解有关进程间通信和进程同步的任何提示

编辑:进程正在相互写入进程的管道。每个进程将发送以下信息:

typedef struct MessageCDT{
    pid_t destination;
    pid_t source;
    int num;
} Message;

所以,只有消息的来源和一些随机数。然后,每个进程都会将消息打印到stdout:process20从进程3收到5724244这样的消息。

整个标志数组似乎都被复制了。当然,在一个进程或另一个进程写入之前,它实际上不会被复制。但这是一个实现细节,对单个流程是透明的。就每个进程而言,它们都会获得数组的一个副本

有很多方法可以避免这种情况发生。您可以将
mmap
MAP\u SHARED
选项一起用于标记所用的内存。然后每个子进程将共享相同的内存区域。还有Posix共享内存(顺便说一句,我认为这是一个可怕的黑客攻击)。要了解Posix共享内存,请查看手册页

但是以这种方式使用内存并不是一个好主意。在多核系统上,当一个进程(或线程)写入共享内存区域时,所有其他进程都会立即看到写入的值,这并不总是这样。该值通常会在二级缓存中挂起一段时间,不会立即刷新


如果要使用共享内存进行通信,则必须使用互斥体或C++11原子操作,以确保其他进程正确地看到写入操作。

Unix进程具有独立的地址空间。这意味着一个内存与另一个内存完全分离。当您调用fork()时,您将获得流程的新副本。从fork()返回时,两个进程之间唯一不同的是fork()的返回值。这两个进程中的所有数据都是相同的,但它们是副本。除非您采取步骤共享内存,否则一方无法知道另一方的内存更新情况

Unix中的进程间通信(IPC)有很多选择,包括共享内存、信号量、管道(命名和未命名)、套接字、消息队列和信号。如果你用谷歌搜索这些东西,你会发现很多东西值得一读

在您的特定情况下,尝试让几个进程等待它们全部到达某个点,我可能会使用信号量或共享内存,这取决于是否有某个主进程启动了它们

如果有一个主进程启动其他进程,那么主进程可以设置一个与要同步的进程数相等的信号量,然后启动它们。然后,每个子级可以减小信号量值,并等待信号量值达到零

如果没有主进程,那么我可能会创建一个共享内存段,其中包含进程计数和每个进程的标志。但是,当您有两个或多个进程使用共享内存时,您还需要某种锁定机制(可能还是一个信号量)来确保两个进程不会同时尝试更新共享内存

请记住,读取无人写入的管道将在数据出现之前阻止读卡器。我不知道你的进程是做什么的,但也许同步就足够了?另一个要考虑的是,如果有多个进程写入给定的管道,如果写入大于PIPEIBUF,它们的数据可能会交错。此宏的值和位置取决于系统


-Kevin

你能发布更多关于流程的信息吗?他们在做什么?为什么不使用线程呢?为什么要使用一组标志而不是一个控制进程来控制所有其他进程?@FranziskusKarsunke很抱歉,我已经更新了信息。这只是一个家庭作业。多线程不是我正在研究的。你能详细说明一下控制过程是如何工作的吗。。。如果这是一项作业,你应该自己做^^@FranziskusKarsunke我只是想了解一个概念,也许还有一些提示。我不是在寻找实际的代码。因此,如果一个进程写入数组的一个索引,其他进程将不会看到此更改?@seljuq70:不,不会。在
fork
调用之后,进程之间不会共享内存,除非您显式地做了一些事情使其发生。这就回答了这个问题。是共享内存,谢谢您的帮助。@seljuq70:即使使用共享内存,您也必须确保处理器缓存保持适当的同步。一个共享的标志数组可能会产生你意想不到的奇怪结果。正如你所知,没有现代*nix会复制整个地址空间。他们进行写时复制,排列页表条目,使两个地址空间指向同一个内存,直到其中一个试图写入给定页,才进行复制。