管道是针对本地计算机的两个进程之间的通信而设计的,管道建立后,实际获得两个文件描述符:一个用于读取而另外一个用于写入。任何从管道写入端写入的数据,可以从管道读取端读出。特点:
管道是半双工的,数据只能向一个方向流动,需要双方通信时,需要建立起两个管道。
只能用于父子进程或者兄弟进程之间
单独构成独立的文件系统:管道对于管道两端的进程而言,就是一个文件,它不属于某种文件系统,而是单独构成一种文件系统,并且只存在于内存
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读取数据
fifo克服了管道,只有亲缘关系才能通信的瓶颈。这个下次再说。
例子:
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*define a function pid_printf*/
void pid_printf(char *format, ...)
{
va_list ap;
va_start(ap, format);
printf("[%d]%d:", getpid(),__LINE__);
vprintf(format, ap);
}
/*chile write data to pipe*/
void child_process(int pfd[2])
{
close(pfd[0]); //close unused read fd
char buf[256];
pid_printf("child process is ready.\n");
pid_printf("enter message(ctrl+d to exit):");
fflush(stdout);
while(fgets(buf, sizeof(buf), stdin) != NULL)
{
pid_printf("Transmitting message:%s",buf);
write(pfd[1], buf, strlen(buf));
}
pid_printf("child process exiting.\n");
close(pfd[1]);
_exit(EXIT_SUCCESS);
}
/*parent read data from pipe*/
void parent_process(int pfd[2])
{
char buf[256] = {0};
int count;
int status;
/*close unused write fd*/
close(pfd[1]);
pid_printf("parent process is ready.\n");
while(1)
{
count = 0;
while(count < sizeof(buf)-1)
{
status = read(pfd[0], buf+count, 1);
if(status < 1)
{
pid_printf("read eof, parent exiting\n");
close(pfd[0]);
return;
}
if(buf[count] == '\n')
break;
count ++;
}
pid_printf("receive message:%s\n", buf);
}
pid_printf("no more data , parent exiting\n");
close(pfd[0]);
}
int main(int argc, char *argv[])
{
int pfd[2];
pid_t pid;
if(pipe(pfd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if(pid == 0)
{
child_process(pfd);
}
else if(pid!=-1)
{
parent_process(pfd);
}
return 0;
}
/*管道主要是使用pipe()函数*/