在C中fork后,从SHM编辑结构中的变量

时间:2014-01-26 18:36:15

标签: c fork pipe ipc shared-memory

以下问题:

我创建了一个共享内存段(在我的main.c中),包含多个结构,一些变量等。在那之后,我是 - 创建一个管道,和 -fork() - 。ING

我正在创建子进程,父进程通过管道进行通信 - 其套接字描述符都存储在全局结构中,保存在共享内存段中。 现在我读到了包含在共享内存段中的元素,在分叉之后,两个进程都可以操作共享变量和结构,并且共享内存的另一个进程因此可以访问相同的操作数据。到目前为止,太棒了!

我的问题不是一个源代码问题,它更像是一个我似乎缺少的理论观点,因为我的代码完全按照应有的方式工作,但我不明白为什么会这样:

在分叉之后,我让每个过程关闭它(与我的目的无关),管道的一侧(例如,父母关闭管道的阅读侧,孩子是书写侧)。但是,pipe_fd [2]存储在SHM段的全局结构中。那么,如果一方从一个进程关闭,另一方从另一个进程关闭(分别通过使用

访问)怎么办?
 close(nameOfSHMStruct->pipe_fd[0]);

 close(nameOfSHMStruct->pipe_fd[1]);

),但是它们都是从结构中访问它们,它们仍然可以相互通信吗?我错过了关于pipe() - 语句的东西,或者是SHM的东西,还是fork()的东西,或者上帝知道它们中的所有3个的组合?正如我已经说过的那样,代码实际上是这样工作的,我打印(作为调试消息),进程之间交换的数据,但我真的没有真正得到它的运作方式背后的核心理论方面......

2 个答案:

答案 0 :(得分:2)

他们能够沟通,因为他们只关闭他们的管道描述符。我会深刻解释:

FATHER PROCCESS          ----->  FORK() ------>>> FATHER PROCESS

pipe() -> pipe_fd[2]                     |         pipe_fd[2] (father pipe fds)
                                         |
                                         ----->>> CHILD PROCESS
                                                  pipe_fd[2] (child pipe fds)

fork克隆父进程,包括文件描述符:child拥有其父进程的文件描述符的副本。所以在fork之后,我们将为每个进程提供2个文件描述符。

因此,考虑到这一点,你不应该将管道文件描述符存储在共享内存结构中,因为它指向父亲和孩子们在概念上不同的fd。

Herehere更多信息。

答案 1 :(得分:1)

查看更多代码会很有帮助,但我会猜测。

使用对pipe()的调用创建的'pipe_fd'将在fork()时复制到子进程。由于内存空间也在fork上复制,因此shm对象中的指针明显指向父或子中的内存地址。因此,即使在shm中的'pipe_fd'上,调用close也实际上分别指向父或子中的'pipe_fd'。

我想更容易看到它是:你所有放在shm对象中的是一个指针,它在进程间共享,并且由于地址空间被复制(包括pipe_fd),指针指向到父或子的同一地址,这是他们自己的'pipe_fd'副本。