Unix系统早期一般使用多进程解决问题。有时多个进程之间需要交互数据,而进程和进程之间不能直接交互数据,因此引入了进程间通信(IPC)。

 

IPC主要包括以下方式:

1. 文件I/O

2. 信号

3. 管道

4. 共享内存

5. 消息队列

6. 信号量集

7. 网络socket

其中,共享内存、消息队列和信号量集都遵循XSI IPC,因此三者编程中有很多共性。管道目前很少使用。

 

 

管道(FIFO或PIPE)之所以目前很少使用,是由于他有两点局限性:

1. 一般为半双工(即同一时刻,数据只能在一个方向流动,也就是不能同时传输)。

2. 管道只能在两个有共同祖先进程的两个进程之间使用。

 

管道分为有名管道(有文件名)和无名管道(没有名字)。有名管道就是自己创建管道文件,然后进行交互。无名管道就是系统帮我们创建管道文件,利用系统的管道文件进行交互。

也就是有名管道适用于所有的进程的通信,无名管道只适用于fork()创建的父子进程之间的通信。

 

管道也是一个文件,后缀名为.pipe。我们可以使用mkfifo命令或mkfifio()函数创建一个有名管道文件:

$ mkfifo a.pipe

mkfifo函数定义如下:

#include<sys/types.h>
#include<sys/stat.h>

int mkfifo(const char * pathname,mode_t mode);

/* 示例 */
mkfifo("a.pipe", 0777);    /* 成功返回0,失败返回-1,错误代码存在errno中 */

 

读管道示例代码如下: 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <fcntl.h>
 5 
 6 int main()
 7 {
 8     int fd = open("a.pipe", O_RDONLY);
 9     if (fd == -1)
10         perror("open"), exit(-1);
11 
12     int x = 0;
13     while (1) {
14         int res = read(fd, &x, sizeof(x));
15         if (res == -1) {
16             perror("read");
17             close(fd);
18             exit(-1);
19         }
20         if (!res) break;
21         printf("x=%d\n", x);
22     }
23     close(fd);
24 
25     return 0;
26 }
View Code

相关文章: