管道
管道是一种古老的IPC通信形式。它有两个特点:
- 半双工,即不能同时在两个方向上传输数据。有的系统可能支持全双工。
- 只能在父子进程间。经典的形式就是管道由父进程创建,进程fork子进程之后,就可以在父子进程之间使用了。
- 进程创建管道,每次创建两个文件描述符来操作管道。
- 其中一个对管道进行写,另一个对管道进行读操作。
声明
使用popen函数和pclose函数结合来执行系统命令,就用到了管道,它们声明如下:
FILE *popen(const char *command,const char *type);
int pclose(FILE *stream);
#include <unistd.h>
int pipe(int filedes[2]);
- filedes是一个文件描述符的数组,用于保存管道返回的两个文件描述符。
- 下标为0是为了读操作而创建打开的,下标为1是为了写操作而创建打开的。
- 执行成功返回0;失败返回1;
例子
我们看一个简单的使用管道的例子,这里使用了pipe函数来创建管道:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#define MAX_LEN 128
int main()
{
/*0为读,1为写*/
int fd[2] = {0}; //描述符
pid_t pid = 0;
char line[MAX_LEN] = {0};
int n = 0;
/*创建管道,需要传入两个文件描述符*/
if(pipe(fd) < 0)
{
perror("create pipe failed\n");
return -1;
}
/*fork子进程*/
if((pid = fork()) < 0)
{
perror("fork failed\n");
return -1;
}
/*父进程*/
else if(pid > 0)
{
/*关闭管道的写描述符*/
close(fd[1]);
/*从管道读取数据*/
n = read(fd[0],line,MAX_LEN);
printf("read %d bytes from pipe :%s\n",n,line);
}
/*子进程*/
else
{
/*关闭管道的读描述符*/
close(fd[0]);
/*向管道写入数据*/
write(fd[1],"www.yanbinghu.com",sizeof("www.yanbinghu.com"));
}
return 0;
}
在程序中,
- 我们创建了一个管道,父进程关闭了写通道,子进程关闭读通道;
- 子进程向管道内写入字符串,而父进程从管道中读取字符串并输出。
运行结果:
read 18 bytes from pipe :www.yanbinghu.com