fork创建进程和利用匿名管道进程间的通讯
如果要使用匿名管道,那么我们必须调用pipe函数来进行创建,其原型如下:
#include <unistd.h>
int pipe(int file_descriptor[2]);
我们可以看到pipe函数的定义非常特别。当返回值为0时,则在数组中保存两个新的文件描述符;如果返回-1,那么便是调用失败。
数组中的两个文件描述符以一种特殊的方式连接起来,数据基于先进先出的原则,写到file_descriptor[1]的所有数据都可以从file_descriptor[0]读回来。由于数据基于先进先出的原则,所以读取的数据和写入的数据是一致的。
这里需要特别注意的是,不要用file_descriptor[0]写数据,也不要用file_descriptor[1]读数据!因为其行为未定义的,但在有些系统上可能会返回-1表示调用失败。数据只能从file_descriptor[0]中读取,数据也只能写入到file_descriptor[1],不能倒过来。
那么接下来,我们看一下例子。我们首先在原先的进程中创建一个管道,然后再调用fork创建一个新的进程,最后通过管道在两个进程之间传递数据,源代码如下:
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_BUFFER 25
int main ()
{
int fpid = 0; //fpid表示fork函数返回的值
int fd[2];
if(pipe(fd) == -1)
{
printf("Failed to create pipe!\n");
exit(EXIT_FAILURE);
//return 0;
}
/**
*fork()相当于父进程克隆了一个自己。
*子进程不会重新执行fork之前的代码,它只会执行fork之后的
*/
fpid=fork();
if (fpid < 0)
{
printf("error in fork!");
exit(EXIT_FAILURE);
}
else if (fpid == 0) //返回值等于零处于子进程
{
printf("Child process start, process id is %d\n",getpid());
char bufWrite[MAX_BUFFER] = "Hello,管道";
write(fd[1],bufWrite,strlen(bufWrite) + 1);
//Release resource
close(fd[0]);
close(fd[1]);
printf("[Child process] finish!\n");
}
else //返回值大于零处于父进程
{
printf("Parent process start, process id is %d\n",getpid());
char bufRead[MAX_BUFFER] = {0};
int iRead = read(fd[0],bufRead,MAX_BUFFER);
printf("[Parent process]read the data is \"%s\",the size of read is %d!\n",bufRead,iRead);
//Release resource
close(fd[0]);
close(fd[1]);
printf("[Parent process]finish!\n");
}
exit(EXIT_SUCCESS);
return 0;
}