1. 管道通信
1.1 概念
一个进程在管道的尾部写入数据(管道的作用:数据的共享),另一个进程从管道的头部读出数据。
管道包括无名管道和有名管道。无名管道只能用于父进程和子进程间的通信,有名管道可用于运行于同一系统中的任意两个进程间的通信。
1.2 特点
- 管道通讯是单向的,有固定的读端和写端;
- 数据被进程从管道读出后,在管道中的数据就不存在了;
- 当进程去读取空管道的时候,进程会阻塞;
- 当进程往满管道写入数据时,进程会阻塞;
- 管道的容量是64KB(#define PIPE_BUFFERS 16 include/linux/pipe_fs_i.h)
2. 无名管道
2.1 概念
在linux系统中,无名管道一旦创建完成,操作无名管道等同于操作文件。无名管道的读端被视作一个文件;无名管道的写端也被视作一个文件。
2.2 创建无名管道
2.2.1 函数原型
#include <unistd.h>
int pipe(int pipefd[2]);
2.2.2 函数返回值
成功:0 失败:-1
2.2.3 参数说明
两个文件描述符:pipefd[0]和pipefd[1]。
pipefd[0]为读而打开,pipefd[1]为写而打开,pipefd[1]的输出是pipefd[0]的输入。
在linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。因此可以使用read、write、close等函数来访问无名管道。
3. 示例
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void read_data(int pipes[])
{
int c,rc;
close(pipes[1]); //关掉写
while((rc = read(pipes[0], &c ,1)) > 0)
{
putchar(c);
}
exit(0);
}
void write_data(int pipes[])
{
int c ,rc;
close(pipes[0]); //关掉读
while((c = getchar()) > 0)
{
rc = write(pipes[1], &c, 1);
if(rc == -1)
{
perror("\nwrite\n");
close(pipes[1]); //关掉写
exit(1);
}
}
close(pipes[1]);//关掉写
exit(0);
}
int main(int argc, char *argv[])
{
int pipes[2]; /pipe[0]用于读,pipe[1]用于写
int rc;
pid_t pid;
rc = pipe(pipes);
if(rc == -1)
{
perror("\npipes\n");
exit(1);
}
pid = fork();
switch(pid)
{
case -1:
perror("\nfork\n");
exit(1);
case 0: //子进程
read_data(pipes);
break;
default://父进程
write_data(pipes);
break;
}
return 0;
}
编译运行:
[root@192 pipe]# gcc pipe.c -o pipe
[root@192 pipe]# ./pipe
123
123
456
456
789
789