Linux系统编程——管道

文章介绍了管道的基本概念和特性,包括其单向通信、一次性读取的特质,并展示了如何使用pipe函数创建和使用管道。通过实战练习实现了ls|wc-l命令,演示了管道在父子进程间的通信。此外,还提到了FIFO(有名管道)作为解决非血缘关系进程间通信的方法。
摘要由CSDN通过智能技术生成


一、管道

1.管道的特质

  • 实现原理:
    内核借助环形队列机制,使用内核缓冲区实现。

  • 特质:
    1.伪文件
    2.管道中的数据只能一次读取。
    3.数据在管道中,只能单向流动。

  • 局限性:
    1.自己写,不能自己读。
    2.数据不可以反复读。
    3.半双工通信。
    4.血缘关系进程间可用。

2.管道的用法——pipe函数

  • 用处:
    创建并打开管道

  • int pipe(int fd[2]);

  • 参数:
    fd[0]:读端
    fd[1]:写端

  • 返回值:
    成功 0
    失败:-1 error
    在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
void sys_err(const char *str)
{
	perror(str);
	exit(1);
}
int main(int argc,char *argv[])
{
	int ret;
	int fd[2];
	pid_t pid;
	
	char *str = "hello pipe\n";
	char buf[1024];
	
	ret = pipe(fd);
	if(ret == -1)
		sys_err("pipe error");
	pid = fork();
	if(pid > 0){
		close(fd[0]);
		write(fd[1],str,strlen(str));
		close(fd[1]);
	}else if(pid == 0){
		close(fd[1]);
		ret = read(fd[0],buf,sizeof(buf));
		write(STDOUT_FILENO,buf,ret);
		close(fd[0]);
	}
	return 0;
}

3.管道的读写行为

读管道:

  • 1.管道有数据,read返回实际读到的字节数。
  • 2.管道无数据:
    1)无写端,read返回0(类似读到文件尾)
    2)有写端,read阻塞等待。

写管道:

  • 1.无读端,异常终止。(SIGPIPE导致的)
  • 2.有读端:
    1)管道已满,阻塞等待
    2)管道未满,返回写出的字节个数。

4…管道的优劣

  • 优点:
    简单,相比信号,套接字实现进程间通信,简单很多。
  • 缺点:
    1.只能单向通信,双向通信需建立两个管道。
    2.只能用于歌子、兄弟进程(有共同祖先)间通信。该问题后来使用fifo有名管道解决。

二.实战练习:实现ls | wc -l 指令

  • 该指令功能:
    统计目录中的文件数
  • 所需函数:
    创建管道函数pipe();
    创建子进程函数fork();
    执行系统级函数(接管子进程函数)execlp();
    重定向函数dup2();
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
void sys_err(const char *str)
{
	perror(str);
	exit(1);
}
int main(int argc,char *argv[])
{
	int fd[2];
	int ret;
	pid_t pid;
	ret = pipe(fd);
	if(ret == -1){
		sys_err("pipe error");
	}
	pid = fork();
	if(pid == -1){
		sys_err("fork error");
	}else if(pid > 0){		//父进程执行wc -l
		close(fd[1]);
		dup2(fd[0],STDIN_FIFLENO);
		execlp("wc","wc","-l",NULL);
	}else if(pid == 0){
		close(fd[0]);
		dup2(fd[1],STDOUT_FIFLENO);
		execlp("ls","ls",NULL);
		//不能用close,因为execlp走了就不回来了
	}
	return 0;
}

三、fifo实现非血缘关系进程间通信

先当于先创建管道文件
在对文件进行读写操作
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strive_LiJiaLe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值