IPC -interprocesscommunication就是指进程间的通信。一个程序往往要有很多进程协作来完成。那么各个进程间的通信就很重要了,这是在 Unix/Linux下经常遇到的问题之一,它的主要目的就是要多个进程可以相互访问数据。
只有一个进程的程序,IPC没有什么意义。
这次主要学习管道通信。管道是最基本的,最简单的IPC 方式。
管道在系统中并没有一个实际的名字,它只存在于内存中,一旦程序运行结束,管道也就消失了。
创建管道:
int pipe(int fds【2】);
fd【2】 是一个整型数组,包含两个元素,分别为fd【0】和fd【1】,fd【0】表示管道的读端,fd【1】表示管道的写入端。管道两端的功能是固定的,只能从fd【0】读数据,只能从fd【1】写数据。
该函数创建管道成功,返回0;否则返回-1.
管道通信主要用于具有共同祖先的进程间通信,及父子进程或兄弟进程间通信。
读管道进行读写操作可以使用read()和write()。当对一个读端已经关闭的管道写入数据会产生SIGPIPE信号,表明管道读端已经关闭。而write()操作会返回-1,errno的值为EPIPE,对于SIGPIPE信号可以进行捕捉处理。
对一个管道进行读操作,read()函数返回0有两种可能,一种是管道中无数据并且管道写端已经关闭,另一种就是,管道中无数据,但是管道写入端依然存在,这两种情况要分别处理。
下面演示一个简单的父子进程间通信的例子。
我们可以先创建一个管道,然后fork()一个子进程。但是之后子进程会继承父进程的数据段,也就是父子进程对创建的管道都具有操作权,父子进程间通信数据的流向要看我们如何维护刚创建的管道。
我们要达到从父进程向子进程传递消息的目的。我们可以把父进程中管道的读端fd[0]关闭,只留写入端 fd[1],而对于子进程我们可以把管道的写入端fd[1]关闭,只保留读出端fd[0]
下面是一段简单的测试从父进程向子进程发送消息的代码:
1#include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<limits.h>
5 #include<sys/types.h>
6 #include<fcntl.h>
7 #define BUFFERSIZE PIPE_BUF
8
9 int main()
10 {
11 pid_t pid;
12 int fd[2];
13 char buffer[BUFFERSIZE];
14 ssize_t len;
15
16 if((pipe(fd))<0)
17 {
18 perror("创建管道失败!");
19 exit(1);
20 }
21
22 pid = fork();
23 if(pid<0)
24 {
25 perror("创建子进程失败");
26 exit(1);
27 }else if(pid == 0)
28 {
29 close(fd[1]);
30 len = read(fd[0],buffer,BUFFERSIZE);
31 if(len < 0)
32 {
33 perror("读取数据失败");
34 exit(1);
35 }
36 else{
37 write(STDOUT_FILENO,buffer,len);
38 }
39 }else{
40 close(fd[0]);
41 write(fd[2],"this is a test to child\n",25);
42 exit(0);
43 }
44 return 0;
45 }
46
47
1,17 顶端
41,12-18 66%