管道的自我实现,如何知道有多少进程有我的管道的文件描述符?

时间:2014-12-12 09:45:24

标签: c linux pipe fork file-descriptor

我需要自行实现一个管道,它具有pipe()read()write()close()的常规管道功能。管道用作父进程和子进程之间的通信通道,这意味着程序将使用fork(),可能不止一次。

我的想法是使用pipe()函数中的malloc来实现它,该函数将在close()函数中释放,但是当fork命令发生时,我将最终有多个进程持有一个文件描述符到我的管道,这是我无法弄清楚的部分:

我怎么知道调用fork()多少次以及有多少进程可以访问我的管道? 如何阻止关闭其管道一端访问权限的进程为其他所有进程关闭?如何确保关闭管道的最后一个进程将释放其内存?

  

更新

实际上它意味着使用文件描述符,并且进程不管理这个内存,他们只能访问它,我需要一种方法来阻止一个进程关闭它的一端在它被所有其他人关闭之前,并确保一旦所有结束都关闭,内存就会被释放。

3 个答案:

答案 0 :(得分:3)

我认为您要做的是实现pipe()之类的内容,但不实际使用pipe()(甚至是FD),而是使用内存。

当程序执行fork()时,其子系统和父级都可以使用其FD。因此,使用pipe(),孩子可以写,父母可以阅读(反之亦然)。但是,子进程会继承父进程内存的写时复制副本。因此,父母不会看到孩子所做的任何写作,反之亦然。另一方面,如果使用线程,则内存映射是真正共享的。

您要做的是IPC(进程间通信)的一种形式。如果您不想使用内存,则需要特殊类型的内存。一种方法是使用shmgetshmctl等 - 有一些示例here

但是,您必须自己管理内存分配,而不是使用malloc()free()malloc()free()在堆上运行,不会使用共享内存段。

为了完整性,您的问题的答案在技术上是父母和所有孩子必须每个免费为父母在fork()之前做出的任何分配,因为他们每个人都不仅拥有分配内存,但也分配内存分配控制结构。但是,它们实际上每个都有不同的分配,包含相同的数据(通过写时复制实现)。

答案 1 :(得分:2)

我不确定你的想法,但有些选择是:

  1. 使用命名信号量,每个子项打开并递增,等待它在父项中返回0。这是最简单,最有效的。
  2. 获取每个孩子的PID并使用其中一个等待函数' wait(),wait3(),wait4(),waitpid()'确保他们都退出了。如果您的孩子不退出,该计划可能会暂停。
  3. 解析系统的输出' lsof'命令。此命令可以直接在命名文件上运行,效率不高。

答案 2 :(得分:1)

我认为你应该检查一下与execve()一起使用的waitpid手册。 它为您提供了儿子过程的返回值。

你可以在github上查看我自己的实现:

https://github.com/sirignano/environnement_unix_1/tree/master/42sh

我认为 ft_pipe.c和ft_use.c 是你在找什么。 (不太确定:D)