Tim*_*Tim 21 shell pipe system-calls architecture
当我刚刚在 bash 中使用管道时,我没有考虑更多。但是当我阅读一些使用系统调用 pipe() 和 fork() 的 C 代码示例时,我想知道如何理解管道,包括匿名管道和命名管道。
经常听到“Linux/Unix 中的一切都是文件”。我想知道管道是否实际上是一个文件,以便它连接的一部分写入管道文件,另一部分从管道文件读取?如果是,创建的匿名管道的管道文件在哪里?在 /tmp、/dev 或 ...?
但是,从命名管道的例子中,我也了解到使用管道比显式使用临时文件具有空间和时间性能优势,可能是因为管道的实现不涉及文件。此外,管道似乎不像文件那样存储数据。所以我怀疑管道实际上是一个文件。
jfg*_*956 23
关于您的性能问题,管道比文件更有效,因为不需要磁盘 IO。Socmd1 | cmd2比cmd1 > tmpfile; cmd2 < tmpfile(如果tmpfile作为命名管道支持在 RAM 磁盘或其他内存设备上,则效率更高;但如果它是命名管道,cmd1则应在后台运行,因为如果管道变满,其输出可能会阻塞)。如果你需要的结果cmd1,仍然需要将其输出发送到cmd2,你应该cmd1 | tee tmpfile | cmd2将允许cmd1和cmd2并行运行,避免从磁盘读操作cmd2。
如果许多进程读/写同一个管道,命名管道很有用。当程序不是设计为将 stdin/stdout 用于需要使用文件的IO 时,它们也很有用。我将文件用斜体表示,因为从存储的角度来看,命名管道并不完全是文件,因为它们驻留在内存中并且具有固定的缓冲区大小,即使它们具有文件系统条目(供参考)。其他的事情在UNIX文件系统有没有条目被文件:只要想/dev/null或其他条目/dev或/proc。
由于管道(命名和未命名)具有固定的缓冲区大小,对它们的读/写操作可能会阻塞,导致读/写过程进入 IOWait 状态。另外,从内存缓冲区读取时什么时候会收到 EOF ?这种行为的规则定义明确,可以在男人身上找到。
你不能用管道(命名和未命名)做的一件事是在数据中寻找。因为它们是使用内存缓冲区实现的,所以这是可以理解的。
关于"everything in Linux/Unix is a file",我不同意。命名管道具有文件系统条目,但不完全是文件。未命名管道没有文件系统条目(可能在 中除外/proc)。但是,UNIX 上的大多数 IO 操作都是使用需要文件描述符的读/写函数完成的,包括未命名的管道(和套接字)。我不认为我们可以这么说"everything in Linux/Unix is a file",但我们肯定可以这么说"most IO in Linux/Unix is done using a file descriptor"。