进程间通信之管道

时间:2022-06-15 19:04:18

管道是类似于文件读写进程间通信的方式,也是比较古老的进程间通信方式.管道的使用需要在创建管道文件,进程通过对该文件读写来完成通信,管道文件并不会占用磁盘空间.必须管道内有信息的时候才能对管道内进行读取.否则会IO堵塞.程序被堵塞.而且管道两端被打开以后才可以进行读写,否则IO堵塞.个人比较喜欢使用信号和管道配合使用,当对管道进行了写操作以后发送信号给相关进程,当相关信号来了以后对管道文件进行读取.这样有效的避免了IO堵塞造成程序没法进行其他的操作.

管道分为有名管道(FIFO)和无名管道(PIPE):

  1. 管道使用的一般步骤:
  2. 初始化管道文件系统
  3. 注册和加载管道
  4. 建立读和写管道
  5. 进行读写
  6. 使用结束以后关闭管道文件

 

一,无名管道:只能在有亲缘关系的进程之间才能使用.

头文件<unistd.h>
int pipe(int filedes[2]);//建立无名管道(父子进程间的通信)

 

  1. int p[2]; //管道文件描述符
  2. char buf[16];
  3. char buf0[16];
  4. pid_t pid;
  5. strcpy(buf,"Hello World!");
  6. pipe(p);//注册管道
  7. pid = fork()
  8. if(pid > 0){
  9. write(p[1], buf, strlen(buf));  //对管道进行写操作
  10. //关闭管道文件描述符
  11. close(p[1]);
  12. close(p[2]);
  13. }
  14. if(pid == 0){
  15. read(p[0], buf0, sizeof(buf0));//对管道进行读操作
  16. printf("%s\n", buf0);
  17. close(p[0]);
  18. close(p[1]);
  19. }
  20. if(pid < 0){
  21. exit(1);
  22. }

二,有名管道:任意进程均可通过此方式进行通信

头文件<sys/types.h> <sys/stat.h>//建立有名管道(无关进程的通信)
int mkfifo(const char * pathname,int mode);
根据pathname创建特殊的FIFO文件,mode是该文件的权限
返回值:0成功,-1失败

 

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <unistd.h>
9
10 #define FIFO_PATH "/home/linux/myfifo"   //管道文件
11
12
13 int main(int arge,char *argv[])
14 {
15 int fdw = 0; //读文件描述符
16 int fdr = 0;//写文件描述符
17 char cwrite[8] = {0};
18
19 if(arge != 2){
20 printf("参数输入错误\n");
21 return -1;
22 }
23
24 if(mkfifo(FIFO_PATH,0666) < 0 && errno != EEXIST){//注册管道文件
25 printf("创建错误\n");
26 return -2;
27 }else{
28 fdw = open(FIFO_PATH, O_CREAT | O_WRONLY,0666);//打开写管道
29 fdr = open(argv[1],O_CREAT | O_RDONLY,0666);//打开读管道
30 //进行读写管道的操作
31 if(fdw > 0){
32
33 if(fdr > 0){
34 while(read(fdr,cwrite,7) > 0){
35 write(fdw,cwrite,7);
36 memset(cwrite,0,sizeof(cwrite));
37 }
38
39 }else{
40 printf("%s文件打开失败\n",argv[1]);
41 return -3;
42 }
43
44 }else{
45 printf("管道打开失败\n");
46 return -4;
47 }
48 }
49 //关闭文件描述符
50 close(fdw);
51 close(fdr);
52
53 return 0;
54 }