Linux进程间通信完整总结

本文详细介绍了Linux进程间通信的多种方法,包括管道通信(标准流管道、无名管道、命名管道FIFO)、System V的共享内存、信号量和消息队列,以及Linux系统的信号处理。通过具体的创建、操作和使用流程,帮助读者深入理解这些通信机制的工作原理和应用场景。
摘要由CSDN通过智能技术生成

一、管道通信

管道的特点

  • 1.管道是一个字节流
  • 2.管道是单向的
  • 3.管道的容量是有限的
  • 4.管道一次写入数量最大为PIPE_BUF。多进程同时写入时,如果超过了这个数量,可能会发生数据混合。
  • 5.当管道中不存在数据时,read操作会阻塞(如果管道写端已经关闭,read操作会返回0)

1.标准流管道

  • 1. 打开关闭标准流管道

  • 打开操作
    使用popen函数创建。一般用于父子进程间的通信。
    在这里插入图片描述

    • 输入:1.shell指令 command,指定打开的程序, 2.管道流的打开方法,指定为w或r
    • 返回: 1.成功:标准输入输出流, 2.失败 NULL
    • popen
      popen()函数1.创建了一个管道,2.然后创建了一个子进程来执行shell,3.而shell又创建了一个子进程来执行command字符。mode参数示一个字符串,它确定调用进程是从管道中读取数据mode 为r,还是将数据写入管道中,mode是w。
      mode的取值,确定了所执行的命令的标准输出连接到管道的写入端还是将其标准输入连接到管道的读取端。
  • 关闭操作
    - 随机管道流式FILE*类型,但关闭不能使用fclose(),必须使用 pclose()函数
    - pclose的输出流,默认是块缓冲模式
    - pclose执行后,进程会进入阻塞状态,直到popen开启的进程结束。
    - 成功时,pclose返回新进程的退出状态,失败时返回-1

  • 2.数据的读写

  • 在调用进程中,管道流的读写使用fread()/fwrite()进行

  • 在开启的新进程中,管道流的读写使用scanf()和printf()进行

  • 3.使用流程

//1.创建标准流管道,将其设置为只读模式
FILE* pipe = popen("./hello","r");
//2.从pipe中读取数据
char msg[100] = {
   0};
int ret = fread(msg,1,100,pipe);
//3.关闭流
pclose(pipe);

//hello.c向pipe中写入数据的方法
printf("hello,world");

2.无名管道PIPE

  • 特点:
    1. 只能在亲缘关系进程间进行通信(父子或兄弟)
    2. 半双工
    3. 无名管道是特殊的文件,可以用read\write读写,只能在内存中
  • 创建方法
    无名管道是利用文件描述符来创建管道文件,创建成功后,会分别传回管道文件的读端和写端的文件描述符。因此,只可以用于共享文件描述符的进程之间的通信。
    在这里插入图片描述一般使用第二种形式比较多一些;
    • 传入参数 int数组,大小为2,用于接收返回的管道文件描述符,pipefd[0]为读端,pipedf[1]为写端
    • 返回 正常返回0,错误返回-1.
    • 使用第三种形式时,如果flags指定0,和第二种一样。
      flags 可以指定为
      O_NONBLOCK 设定为非阻塞模式。
      O_DIRECT 设定为包传输模式,每次read/write会向管道中读取/写入一个数据包。(连续发送数据时不会粘在一起)
  • 读取和写入操作
    正常使用read/write对文件描述符进行操作即可
  • 关闭操作
    使用close操作来关闭管道的文件描述符即可。
    需要注意的是,
    • 管道的写端先关闭时,读端会返回0,并不会报错,此时根据读端返回的数值进行管道的关闭即可。
    • 管道的读端先关闭,则写端进程会收到到SIGPIPE信号,进程异常终止;如果写端处理了SIGPIPE信号,则会返回一个负值,表示管道读端已经关闭。
  • 使用流程
//1.创建无名管道文件
int fdp[2] = {
   -1};
int ret = pipe(fdp);
if(-1 == ret) {
   
	perror("pipe");
	exit(-1)
}
//2.创建子进程
char msg[100]={
   0};
ret = fork();
if(ret){
   
	if(ret = -1) exit(-1);
	//3.关闭父进程写端,使用读端读取子进程的数据
	close(fd[1]);
	//4.读取数据
	read(fd[0],msg,100);
	printf("msg:%s\n",msg);
	wait(NULL);
	//5.关闭读端
	close(fd[0]);
}else {
   
	//3.关闭子进程读端,使用写端
	close(fd[0]);
	//4.写入数据
	write(fd[1]."hello,world",11);
	//5.关闭写端
	close(fd[1])
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值