【linux】mkfifo 命令创建命名管道实现进程之间通信

本文介绍了mkfifo命令的使用方法及特点,这是一种用于创建命名管道的工具,可用于进程间通信。文章通过实例演示了如何创建、查看及使用这些管道进行一对多或多对一的数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mkfifo 命令

  • mkfifo命令创建一个FIFO特殊文件,是一个命名管道(可以用来做进程之间通信的桥梁)
  • 管道也是一种文件,一般是linux中的一个页大小,4k,管道数据一旦被读取就没了。(管道大小和管道的buff大小理解有错误,请看 pipe-buffer-size-is-4k-or-64k?
  • 管道是单方向
  • mkfifo命令文档

使用命名管道

下面均是再OSX系统实验。

创建管道
liuzhizhi@lzz-rmbp|pipe # mkfifo log.pipe
查看管道
liuzhizhi@lzz-rmbp|pipe # ls -l
total 0
prw-r--r-- 1 liuzhizhi staff 0 10 14 22:21 log.pipe

仔细看下最前面的部分 开头是 p,表示这是一个管道

使用管道
  • 一对一的情况
#第一个窗口
# ls -l > log.pipe

#第二个窗口
# cat < log.pipe
total 0
prw-r--r-- 1 liuzhizhi staff 0 10 14 22:25 log.pipe

这里管道并不是水桶,当我们执行 ls -l > log.pipe 的时候,这里就开始阻塞了,只有当我们再第二个窗口执行 cat < log.pipe 的时候,第一个窗口的ls命令才执行完。

所以这里的管道非常形象,它只是负责传输,虽然它也能存点水,但只有实用的时候才能存住一点水,如果只有一端倒水或者只有一端接水,都是无法正常运行的。

  • 一个输入,多个接收的情况
#窗口1 
cat < log.pipe

#窗口2 
cat < log.pipe

#窗口3
echo "lzz" > log.pipe

执行的结果是窗口2输出了 lzz,第一个窗没有输出,说明接收方无论多个只能获取一份水,只要被一个接收方接受到,另外一个就无法获取了(所以他不是订阅型的),通过持续往管道输入可以看到,接收方应该是基于抢占式的。

  • 多个输入,一个接受的情况

这里写了一个python程序来做为持续的输入

#coding:utf-8
#logpipe.py
import time
import sys

word = sys.argv[1]

while 1:
    print >> sys.stdout, word
    time.sleep(1)

测试

#窗口1 
cat < log.pipe

#窗口2 
python logpipe.py win1 > log.pipe

#窗口3 
python logpipe.py win2 > log.pipe

#输出
win2
win2
win2
win2
win1
win1

其实这种情况,比较好理解,有个下水道大家都往里面倒水,最后汇总到一个口流出来,由于有缓冲区,所以并不会马上读取到结果。

小结

当然我们这里是用bash 操作这个命名管道,其实基本所有的语言都可以使用这个工具,例如bash命令写入管道,python读取,lua读取。

为什么想到这个东西呢,例如实时读取和处理tcpdump抓包,用c来开发成本有点大,用其他语言当然也可以,但是硬件条件有不允许,所以只好通过管道的方式输出到一个非常廉价的小程序来处理喽。

04-15
### mkfifo 命令详解 `mkfifo` 是一个用于创建命名管道(FIFO 文件)的命令命名管道是一种特殊的文件类型,允许不相关的进程之间通过它进行单向通信。以下是关于 `mkfifo` 的详细介绍: #### 创建 FIFO 文件 `mkfifo` 可以用来创建一个命名管道文件。其基本语法如下: ```bash mkfifo [选项] 名字 ``` 常见的选项包括 `-m` 来指定权限模式[^3]。 例如,下面的例子展示了如何创建一个名为 `/tmp/my_pipe` 的 FIFO 文件,并赋予特定权限: ```bash mkfifo -m 644 /tmp/my_pipe ``` 这会创建一个具有只读权限给其他用户的 FIFO 文件。 #### 使用 FIFO 进行进程通信 一旦 FIFO 被创建,可以像普通文件一样对其进行操作。通常情况下,一个进程负责写入数据到 FIFO 中,而另一个进程则从中读取数据。例如: ```bash # 后台运行一个进程来从管道中读取数据 cat /tmp/my_pipe & # 将消息写入管道 echo "Hello, World!" > /tmp/my_pipe # 删除管道文件 rm /tmp/my_pipe ``` 上述代码片段演示了一个简单的场景:一个后台进程等待从 FIFO 中读取数据,而主线程将字符串 `"Hello, World!"` 写入该 FIFO[^3]。 #### 错误处理与注意事项 如果尝试打开一个不存在或者未被另一端使用的 FIFO 文件,则可能会导致阻塞行为。因此,在实际应用中需要注意以下几点: - 确保至少有一个读者和一个作者同时访问 FIFO。 - 如果不再需要 FIFO 文件,记得及时删除以释放资源。 ### 示例程序展示 FIFO 功能 这里提供一段完整的脚本来说明如何利用 `mkfifo` 实现两个独立脚本之间的通讯功能。 ```bash #!/bin/bash PIPE="/tmp/testpipe" # 清理旧有的 pipe 并新建一个新的 [[ -p $PIPE ]] && rm "$PIPE" mkfifo "$PIPE" # 开启子shell去监听这个pipe的内容 ( while true; do read LINE <"$PIPE" echo "[Received]: $LINE" done ) & CHILD_PID=$! for i in {1..5}; do sleep 1 echo "Message #$i" >"$PIPE" done kill $CHILD_PID wait $CHILD_PID 2>/dev/null rm "$PIPE" exit 0 ``` 此脚本模拟了生产者消费者模型中的简单形式——父进程作为发送方每隔一秒发送一条信息至 FIFO;与此同时开启的一个子 shell 则持续监控接收来自同一 FIFO 的任何新输入直到结束条件达成为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值