管道在 Linux 中如何工作?
- 2024-11-13 08:36:00
- admin 原创
- 20
问题描述:
管道如何工作?如果我通过 CLI 运行程序并将输出重定向到文件,我是否可以在写入文件时将该文件通过管道传输到另一个程序中?
基本上,当将一行写入文件时,我希望它立即通过管道传输到我的第二个应用程序(我正在尝试从现有程序中动态绘制图形)。只是不确定管道是否在继续执行下一个命令之前完成了第一个命令。
如有任何反馈,我们将不胜感激!
解决方案 1:
如果要将一个程序的输出重定向到另一个程序的输入,只需使用一个简单的管道:
program1 arg arg | program2 arg arg
如果要将的输出保存program1
到文件中并通过管道传输到program2
,则可以使用tee(1)
:
program1 arg arg | tee output-file | program2 arg arg
管道中的所有程序都同时运行。大多数程序通常使用阻塞I/O:如果当它们尝试读取输入时没有输入,它们就会阻塞:即它们停止,操作系统取消调度它们运行,直到有更多输入可用(以避免耗尽 CPU)。同样,如果管道中较早的程序写入数据的速度比后面的程序读取数据的速度快,最终管道的缓冲区会填满,写入器会阻塞:操作系统取消调度,直到管道的缓冲区被读取器清空,然后它可以继续再次写入。
编辑
如果要使用的输出program1
作为命令行参数,可以使用反引号或$()
语法:
# Runs "program1 arg", and uses the output as the command-line arguments for
# program2
program2 `program1 arg`
# Same as above
program2 $(program1 arg)
应该优先考虑这种$()
语法,因为它们更清晰,并且可以嵌套。
解决方案 2:
管道在运行第二个命令之前不会完成第一个命令。Unix(和 Linux)管道同时运行所有命令。如果出现以下情况,命令将被暂停:
它极度渴求输入。
它的产量远远超过了其后继者准备消费的产量。
对于大多数程序来说,输出都是经过缓冲的,这意味着操作系统会积累大量的输出(可能是 8000 个字符左右),然后再将其传递到管道的下一阶段。这种缓冲用于避免在进程和内核之间来回切换过多。
如果您希望立即发送管道上的输出,则可以使用无缓冲I/O,这在 C 语言中意味着调用类似的东西fflush()
以确保任何缓冲输出都会立即发送到下一个进程。无缓冲输入也是可能的,但通常是不必要的,因为缺乏输入的进程通常不会等待缓冲区满了,而是会处理您能得到的任何输入。
对于典型的应用程序,不推荐使用无缓冲输出;通常使用默认值可以获得最佳性能。但是,对于您的情况,您希望在第一个进程有可用信息时立即进行动态绘图,您肯定希望使用无缓冲输出。如果您使用 C,fflush(stdout)
则在需要发送输出时调用就足够了。
解决方案 3:
stdin
如果您的程序使用和进行通信stdout
,请确保您fflush(stdout)
在写入后调用或找到某种方法来禁用标准 IO 缓冲。我能想到的真正描述如何在 C/C++ 中最佳实现管道的最佳参考资料是UNIX 环境中的高级编程或UNIX 网络编程:第 2 卷。您也可以从这篇文章开始。
解决方案 4:
如果您的两个程序坚持读取和写入文件并且不使用 stdin/stdout,您可能会发现可以使用命名管道而不是文件。
使用 mknod(1) 命令创建命名管道:
$ mknod /tmp/named-pipe p
然后配置您的程序以读取和写入 /tmp/named-pipe(使用您认为合适的任何路径/名称)。
在这种情况下,两个程序将并行运行,当管道变满/空时根据需要进行阻塞,如其他答案中所述。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件