linux 管道

管道是Unix/Linux系统中的一种进程间通信机制,它通过内核缓冲区实现数据传递。管道分为匿名管道和命名管道,匿名管道主要用于父子进程或兄弟进程之间的单向通信,而命名管道(FIFO)允许不相关进程间通信。管道具有简单易用的特点,但存在数据单向流动、不可反复读取等限制。mkfifo函数用于创建命名管道,而pipe函数用于创建匿名管道。了解管道的使用和限制对于进程间通信至关重要。

管道

管道的特质
  1. 本质是一个伪文件(实质是内核缓冲区)
  2. 由两个文件描述符引用, 一个表示读端, 一个表示写端
  3. 规定数据从管道的写端写入, 读端读出

其原理实则为内核使用环形队列机制, 借助内核缓冲区实现

局限性:

  1. 数据不能由一个进程同时读和写
  2. 不可反复读取管道中的数据, 一旦读走, 则管道将不存在
  3. 采用半双通讯的方式, 数据只能在单方向上流动
  4. 只能在有公共祖先的进程间使用管道

管道的用法

pipe
创建并打开管道
int pipe(int fd[2])
参数:
		fd[0]: 读端
		fd[1]: 写端
返回值:
		成功: 0
		失败: -1

总结

1. 读管道:	
		1. 若有数据, 则read返回实际读到的字节数
		2. 若无数据
				1. 若写端全部被关闭, 则read返回0
				2. 若写端没有被全部关闭, 则read阻塞等待, 让出cpu
				
2. 写管道:
		1. 读端全部被关闭, 进程异常终止(SIGPIPE)
		2. 读端没有全部被关闭:
				1. 管道已满, write阻塞
				2. 管道未满, write将数据写入, 返回实际写入的字节数
		

fpathconf

long fpathconf(int fd, int name);
参数:
		fd: 文件的描述符
		name: 查询的参数
				_PC_PIPE_BUF
				_PC_NAME_MAX
				_PC_LINK_MAX
				_PC_MAX_INPUT
				...

管道的优劣

优点:

	1. 使用简单

缺点:

	1. 只能单向通讯, 双向通讯需要建立两个管道
	1. 只能用于父子, 兄弟进程间的通信

命名管道

mkfifo

int mkfifo(const char *pathname, mode_t mode);
参数:
		pathname: 创建的路径(名字)
		mode: 创建的权限
返回值:
		成功: 0
		失败: -1, 设置 errno
### Linux 管道使用教程 #### 一、基本概念 管道Linux 中一种重要的进程间通信机制,能够将一个命令的标准输出作为下一个命令的标准输入。这种特性使得多个简单工具组合起来完成复杂任务成为可能[^1]。 #### 二、无名管道 无名管道主要用于有亲缘关系的进程间的通讯,即父子进程或者兄弟进程之间。其特点是单向传输数据,并且只能由一对进程访问。创建无名管道通常通过 `pipe()` 函数实现,在调用此函数前建立好管道,则 fork 后子进程中也会拥有该管道副本并可对其进行操作[^4]。 ```c #include <unistd.h> int pipe(int pipefd[2]); // 返回值:成功返回0;失败返回-1 ``` 当执行上述代码后会得到两个文件描述符组成的数组`pipefd[]`,其中第一个元素代表读取端而第二个则是写入端。对于父/子进程来说可以根据需求关闭不需要的那一端来确保不会发生死锁现象。 #### 三、有名管道(FIFO) 相比起无名管道,FIFO 不仅可以在不相关联的进程间传递消息,而且支持全双工模式(尽管大多数情况下还是采用半双工的方式工作)[^3]。要创建 FIFO 文件需借助 mkfifo 命令或是在程序内部利用相应 API 完成: ```bash mkfifo my_fifo_file ``` 之后就可以像对待普通文件一样打开它来进行读写了: ```c #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int fd = open("my_fifo_file", O_WRONLY); write(fd,"hello world\n",strlen("hello world\n")); close(fd); /* 或者 */ int fd = open("my_fifo_file",O_RDONLY); char buf[80]; read(fd,buf,sizeof(buf)); printf("%s",buf); close(fd); ``` #### 四、应用实例 - 统计当前系统中的进程数量 这里给出一个简单的例子展示如何运用 shell 内置功能配合管道达成特定目的——计算正在运行着多少个进程: ```shell ps aux | wc -l ``` 这条指令先列出所有活动进程(`ps aux`)再将其交给单词计数工具处理(`wc -l`),最终得出总数目。 #### 五、注意事项 虽然管道提供了便捷高效的 IPC 方案之一,但在某些场景下或许 TCP/IP 协议栈更为合适,尤其是在跨主机甚至互联网级别的分布式环境中[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值