9、进程间通信:管道

本文介绍了进程间通信(IPC)的几种方式,包括管道(有名管道和无名管道)、信号量和共享内存。管道在内存中创建,允许数据在进程间单向传递,有名管道可用于任意进程间,无名管道限于父子进程。通过示例代码展示了如何使用系统调用创建和使用管道。信号量用于同步多个进程对共享资源的访问。共享内存允许多个进程直接读写同一块内存区域,提高了通信效率。
摘要由CSDN通过智能技术生成

进程间通信(ipc):管道 信号量 共享内存 消息队列 套接字

1、管道

管道如果为空,或者管道写满了,写会阻塞。
在这里插入图片描述

重点:

管道文件是在内存中分配空间,管道文件有一个读端,一个写端。

管道分为:有名管道无名管道。有名管道可以在任意两个进程之间通信,无名管道只能在父子进程之间使用;

**通信方式:**半双工
在这里插入图片描述

有名管道:

1、mkffo FIFO

2、系统调用

管道文件 前面有个p prw-rw-r-- 1 stu stu 0 11月 1 19:20 fifo

**1、**mkffo FIFO

stu@stu-virtual-machine:~$ ls
公共的  模板  视频  图片  文档  下载  音乐  桌面  snap  Test
stu@stu-virtual-machine:~$ mkfifo fifo
stu@stu-virtual-machine:~$ ls
公共的  模板  视频  图片  文档  下载  音乐  桌面  fifo  snap  Test
stu@stu-virtual-machine:~$ ls -l
总用量 40
drwxr-xr-x  2 stu stu 4096 99 17:47 公共的
drwxr-xr-x  2 stu stu 4096 99 17:47 模板
drwxr-xr-x  2 stu stu 4096 99 17:47 视频
drwxr-xr-x  2 stu stu 4096 1018 23:02 图片
drwxr-xr-x  2 stu stu 4096 99 17:47 文档
drwxr-xr-x  2 stu stu 4096 99 17:47 下载
drwxr-xr-x  2 stu stu 4096 99 17:47 音乐
drwxr-xr-x  3 stu stu 4096 920 22:34 桌面
prw-rw-r--  1 stu stu    0 111 19:20 fifo
drwx------  3 stu stu 4096 1010 17:26 snap
drwxrwxr-x 10 stu stu 4096 1030 10:55 Test

读写两个进程必须同时进行,否则将不能正常运行:要使用两个终端来打开这连个进程。

读进程:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<fcntl.h>
  4 #include<unistd.h>
  5 #include<string.h>
  6 #include<assert.h>
  7 int main()
  8 {
  9     int fwr =open("fifo",O_RDONLY);
 10     assert(fwr!=-1);
 11 
 12     printf("fwr=%d\n",fwr);
 13 while(1)
 14 {
 15     char buff[128] = {0};
 16     int n =read(fwr,buff,127);
 17     if(n==0)
 18     {
 19         break;
 20     }
 21     printf("buff=%s,n=%d\n",buff,n);
 22 }
 23     close(fwr);
 24     exit(0);
 25 
 26 }

写程序:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<fcntl.h>
  4 #include<unistd.h>
  5 #include<string.h>
  6 #include<assert.h>
  7 #include<signal.h>
  8 void sig_fun(int sig)
  9 {
 10     printf("sig=%d\n",sig);
 11 }
 12 int main()
 13 {
 14     signal(SIGPIPE,sig_fun);
 15     int fwd =open("fifo",O_WRONLY);//必须有读和写两个进程才能运行。
 16     assert(fwd!=-1);
 17     printf("fwd=%d\n",fwd);
 18     char buff[128]={0};
 19    while(strncmp(buff,"end",3)!=0)
 20    {
 21    memset(buff,0,128);
 22     printf("input:\n");
 23     fgets(buff,128,stdin);
 24     write(fwd,buff,strlen(buff));
 25    }
 26    /*
 27      while(1)
 28      {
 29      memset(buff,0,128);
 30       printf("input:\n");
 31       fgets(buff,128,stdin);
 32       if(strncmp(buff,"end",3)==0)
 33       {
 34       break;
 35       }
 36       write(fwd,buff,strlen(buff));
 37  }
 38  
 39  */
 40     close(fwd);
 41     exit(0);
 42 }

**2、**系统调用

stu@stu-virtual-machine:~/Test/管道举例$ ps -ef | grep bash
stu         2827    2710  0 19:19 pts/0    00:00:00 bash
stu         3930    2827  0 19:53 pts/0    00:00:00 grep --color=auto bash

**无名管道:**pipe

只能在父子进程间使用,pipe(fd)会创造两个文件描述符,用来描述无名管道的读端和写端。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<fcntl.h>
  4 #include<unistd.h>
  5 #include<string.h>
  6 #include<assert.h>
  7 #include<signal.h>
  8 void sig_fun(int sig)
  9 {
 10     printf("sig=%d\n",sig);
 11 }
 12 int main()
 13 {
 14     int fd[2];//fd[0]读 fd[1]15     int res =pipe(fd);
 16     assert(res!=-1);
 17 
 18     pid_t pid =fork();
 19     assert(pid!=-1);
 20 
 21     if(pid==0)
 22     {
 23         close(fd[1]);
 24         char buff[128] ={0};
 25         read(fd[0],buff,127);
 26         printf("child read:%s\n",buff);
 27         close(fd[0]);
 28     }
 29     else
 30     {
 31         close(fd[0]);
 32         char buff[128] ={0};
 33         fgets(buff,128,stdin);
 34 
 35         write(fd[1],buff,strlen(buff));
 36         close(fd[1]);
 37     }
 38     exit(0);
 39 }

stu@stu-virtual-machine:~/Test/管道举例$ ./无名管道
其温泉温泉温泉温泉温泉
child read:其温泉温泉温泉温泉温泉

[1],buff,strlen(buff));
36 close(fd[1]);
37 }
38 exit(0);
39 }


```bash
stu@stu-virtual-machine:~/Test/管道举例$ ./无名管道
其温泉温泉温泉温泉温泉
child read:其温泉温泉温泉温泉温泉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值