同步没有信号量的父级和子级

时间:2016-09-11 20:55:52

标签: c++ c process pipe fork

(没有信号量,或线程,只是进程)

我想从父文件中读取数据并通过管道传递给子文件。 假设文件中的数据是

Is
This
Possible?

现在阅读" Is"通过管道

  1. 孩子如何知道新数据" This"已通过,应阅读
  2. 阅读" Possible?"后,终止条件是什么?通过管道,以便孩子可以在阅读父想要传递的所有数据后终止
  3. (不使用信号量或线程,只是简单的进程i-e分叉)

    先谢谢

2 个答案:

答案 0 :(得分:1)

父母写一个文件并且从中读取的孩子需要您正在考虑的同步。也就是说,如果父亲只写了第一行而孩子已经读过它,但是父母有写了第2行,那么获得过早的EOF。

但是,管道不会。

管道保持打开状态,直到父/发件人关闭它[或子终止]。因此,孩子可以直接读取它直到它收到EOF。

如果没有可用的数据,孩子将自动阻止阅读,但过早获得EOF。如果您愿意,孩子可以select(2)poll(2)检查可用的数据,但我认为这是必要的。

在父母已发送所有数据关闭其管道末尾之前,孩子将获取EOF。

因此,不需要同步。

另一方面,我们可能有一个父母快速发送批次数据,而孩子正在慢慢阅读(即)落后一点。最终,[kernel]管道缓冲区获得了#34; full"父母的写作将会阻止,直到孩子能够“赶上”#34;并排出一些数据。因此,没有数据丢失"。

答案 1 :(得分:0)

您可以使用相当普遍存在的read()fread() API来读取固定数量的数据,并使用这些数据阻止直到有更多数据可用或信号文件结束条件的事实。这是将数据传输到子进程的最直接方式:子进程只需从stdin读取普通文件,直到遇到文件结尾为止。条件。

或者,对于更具响应性/高性能的设计(或处理在文件对象上发出信号的硬件),您需要:

  1. 启用对非阻塞I / O的支持
  2. 使用select()之类的API
  3. 监控输入文件描述符/句柄(管道的读取端)
  4. 与事件循环集成(或自己编写一个简单的循环)
  5. 能够处理意外数量的数据。
  6. 能够处理来自read() / fread()和朋友的错误,尤其是EAGAIN
  7. 并且能够处理文件结束条件。
  8. 接线这意味着深入研究特定于操作系统的API,但幸运的是,它也是一个很常见的任务,存在大量的工具包库(例如libuv,Qt)并提供一致的抽象/更高级别的API。