【发布时间】:2014-11-04 12:48:41
【问题描述】:
如果你有多个通过fork()创建的children,并且与parent通信的方式是“命名管道”,你需要多个命名管道吗?每个孩子一个?或者您可以制作一个并让家长从中读取吗?
基本上,您还有什么需要做的吗?我知道如果多个孩子同时写入同一个命名管道,可能会导致从单个孩子读取整条消息时出现问题。有没有办法确保写入是原子的?
【问题讨论】:
标签: c fork pipe named-pipes
如果你有多个通过fork()创建的children,并且与parent通信的方式是“命名管道”,你需要多个命名管道吗?每个孩子一个?或者您可以制作一个并让家长从中读取吗?
基本上,您还有什么需要做的吗?我知道如果多个孩子同时写入同一个命名管道,可能会导致从单个孩子读取整条消息时出现问题。有没有办法确保写入是原子的?
【问题讨论】:
标签: c fork pipe named-pipes
一个管道可以有多个写入器。但是,正如您所说的通信是在 fork()ed 子级和父级之间进行的,您可能根本不需要 named 管道。命名管道在文件系统中可见,可用于非父/子进程之间的通信。
关于原子性:如果写入少于 PIPE_BUF(不少于 512 字节,Linux 上为 4096 字节,来自 limits.h),则写入是原子性的,不会混合来自不同写入者的消息。如果您写入的内容超过 PIPE_BUF,则不要依赖于原子写入。
PIPE_BUF
POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic: the output data is written to the pipe as a contiguous sequence. Writes of more than PIPE_BUF bytes may be nonatomic: the kernel may interleave the data with data written by other processes. POSIX.1-2001 requires PIPE_BUF to be at least 512 bytes. (On Linux, PIPE_BUF is 4096 bytes.)
【讨论】:
PIPE_BUF 值表:ar.to/notes/posix#pipe-buf
您只能有一个管道、多个写入器和一个读取器。但是为了能够正确阅读,您需要有某种数据结构。您可以简单地为每条消息添加其长度的前缀。如果作者想写点什么,说字符串“hello”,然后它会发送 0x05 和字符串的字节。然后读取是统一的:读取一个字节以获得下一个要读取的字节的长度(两次读取一条消息)。
只要您不写太多,在管道中写入是原子的;不确定,但我认为PIPE_BUF 常量是保证原子性的长度。
【讨论】: