管道是Linux中进程间通信的一种方式,它把一个程序的输出直接连接到另一个程序的输入。
无名管道
1.它只能用于具有亲缘关系的进程间通信(父子进程或兄弟进程之间)
2.是一个半双工的通信模式,具有固定的读端和写端
半双工:指数据可以沿着两个方向传输,但同一时刻一个信道只能允许单方向传送,又称为双向交替通信。
3.可以看作一种特殊的文件,可以使用普通的read()、write()等函数。但它不是普通的文件,并不属于其他任何文件系统且只存在于内存中。
图例
示例
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int pipefd[2];
int pid;
if (pipe(pipefd) < 0){
return -1;
}
pid = fork();
if (pid < 0 ){
return -1;
}else if (pid == 0){
//关闭写入端,从管道读取数据
close(pipefd[1]);
//将管道读取端重定向到0
dup2(pipefd[0], 0);
execl("/usr/bin/wc", "wc", NULL);
}
//关闭管道读取端,写入数据
close(pipefd[0]);
//将管道重定向至1
dup2(pipefd[1], 1);
close(pipefd[1]);
execl("/bin/ls", "ls","-l", NULL);
close(1);
return 0;
}
1.使用pipe创建无名管道
2.子进程关闭写端,从fd[0]读取数据
3.父进程关闭读端,从fd[1]写入数据
4.父进程执行ls, 将结果交给子进程执行wc命令,将最终结果打印出来
命名管道
1.可以使互不相关的连个进程间实现彼此通信
2.该管道可以通过路径名指出,且在文件系统中是可见的。在建立管道之后,两个进程可以把它当做普通文件一样进行读写操作,使用更加方便
3.FIFO严格遵循先进先出规则,对管道及FIFO的读总是从开始处返回数据,写则把数据添加到末尾,不支持如lseek()等文件定位操作。
图例
示例
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void test()
{
printf("test\n");
}
int main(int argc, char *argv[])
{
int fifofd;
char buff[1024];
umask(0);
if (mkfifo("./test.fifo", 0664) < 0){
if (errno != EEXIST){
return -1;
}
}
fifofd = open("./test.fifo", O_RDWR);
if (fifofd < 0){
return -1;
}
while (1){
memset(buff, 0x00, 1024);
read(fifofd, buff, 1024);
if (strncasecmp(buff, "test", 4) == 0){
test();
}
}
close(fifofd);
return 0;
}
1.mkfifo创建管道
2.使用open打开管道文件
3.开始对管道文件进行读写操作
4.通过外部向管道文件写入数据,来实现在程序内部调用test函数,实现指定功能