上一篇博客已经介绍了一种进程间通信的方式,但是那只是针对于有血缘关系的进程,即父子进程间的通信,那对于没有血缘关系的进程,那要怎么通信呢?
这就要创建一个有名管道,来解决无血缘关系的进程通信, fifo:
book@ubuntu:~$ mkfifo xwp book@ubuntu:~$ ls -l myfifo prw-rw-r-- 1 book book 0 Feb 6 2016 myfifo
mkfifo 既有命令也有函数
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
1 /* fifo_write.c */ 2 #include <stdio.h> 3 #include <unistd.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <string.h> 7 #include <fcntl.h> 8 #include <sys/stat.h> 9 10 void sys_err(char *str, int exitno) 11 { 12 perror(str); 13 exit(exitno); 14 } 15 16 int main(int argc,char *argv[]) 17 { 18 int fd, len; 19 char buf[1024] = "hello world "; 20 if(argc < 2) 21 { 22 printf("./app myfifo "); 23 exit(1); 24 } 25 26 fd = open(argv[1],O_WRONLY); 27 if(fd < 0) 28 sys_err("open",1); 29 30 write(fd, buf, strlen(buf)); 31 close(fd); 32 33 return 0; 34 } 35 36 37 38 39 /* fifo_read */ 40 #include <stdio.h> 41 #include <unistd.h> 42 #include <stdlib.h> 43 #include <sys/types.h> 44 #include <fcntl.h> 45 #include <sys/stat.h> 46 #include <string.h> 47 48 void sys_err(char *str, int exitno) 49 { 50 perror(str); 51 exit(exitno); 52 } 53 54 int main(int argc,char *argv[]) 55 { 56 int fd, len; 57 char buf[1024] = {0}; 58 if(argc < 2) 59 { 60 printf("./app myfifo "); 61 exit(1); 62 } 63 64 fd = open(argv[1],O_RDONLY); 65 if(fd < 0) 66 sys_err("open",1); 67 68 read(fd, buf, sizeof(buf)); 69 write(STDOUT_FILENO, buf, strlen(buf)); 70 close(fd); 71 72 return 0; 73 } 74 75 76 操作方法: 77 分别编译成可执行程序:fifo_write 和 fifo_read 78 在一个终端下输入 ./fifo_write myfifo 79 在另一个终端下输入 ./fifo_read myfifo 80 即可观察到结果
注:
- 当只写打开FIFO管道时,该FIFO没有读端打开,则open写打开会阻塞。
- FIFO内核实现时可以支持双向通信。(pipe单向通信,因为父子进程共享同一个file结构体)
- FIFO可以一个读端,多个写端;也可以一个写端,多个读端。
其实fifo指向的还是内核中的缓冲区,只不过他指向所有的内核缓冲区,因此他不是阻塞的,不像pipe只是指向两端,造成阻塞现象