pipe()函数(无名管道)
无名管道特性
- 只能用于有亲缘关系的进程(父子进程、兄弟进程)
- 数据之间单向流动(半双工)
- 管道中数据不存储,数据被读走后便丢失
- 管道并不属于任何文件系统,只存在于内存当中
原函数
#include <unistd.h>
int pipe(int pipefd[2]);
当使用pipe()函数时需创建包含两个文件描述符的数组:
- pipefd[0] —— 管道的读端
- pipefd[1] —— 管道的写端
父子进程间通信
- 建立管道
- 父进程建立子进程(fork()函数)
- 父进程关闭管道的读端(close(pipefd[0]))
- 父进程将数据通过写端写入管道
- 子进程关闭管道写端(close(pipefd[1]))
- 子进程通过读端读取管道中数据
管道如水管一样堵住一端才能将水进行存入或取出操作
示例父进程传数据给子进程:
#include<string.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<stdlib.h>
int main()
{
int fd[2];
int pid;
char buf[128];
if(pipe(fd) == -1)
{
printf("creat pipe failed\n");
}
pid = fork();
if(pid < 0)
{
printf("creat child failed\n");
}
else if(pid > 0)
{
sleep(3);
printf("this is father\n");
close(fd[0]);
write(fd[1],"hello frome father",strlen("hello frome father"));
}else{
printf("this is child\n");
close(fd[1]);
read(fd[0],buf,128);
printf("read from father %s\n",buf);
exit(0);
}
return 0 ;
}
mkfifo()函数(命名管道)
原函数
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
调用mkfifo()函数后,将会创建一个文件格式的命名管道,可以使用对文件的I/O函数进行操作
命名管道特性
若未设置O_NONBLOCK(非阻塞)模式,当单方向(只读或只写)打开该管道时将会导致阻塞(程序无法退出),只有同时对管道操作程序才能正常结束,示例:
只读管道程序:
#include <sys/types.h>
#include <sys/stat.h>
#include<stdio.h>
#include<errno.h>
#include <fcntl.h>
int main()
{
if(mkfifo("./file",0600) == -1 && errno != EEXIST)
{
printf("make fifo defult\n");
perror("why");
}
int fd = open("./file",O_RDONLY);
printf("open succse\n");
return 0;
}
只写管道程序
#include <sys/types.h>
#include <sys/stat.h>
#include<stdio.h>
#include<errno.h>
#include <fcntl.h>
int main()
{
if(mkfifo("./file",0600) == -1 && errno != EEXIST)
{
printf("make fifo defult\n");
perror("why");
}
int fd = open("./file",O_WRONLY);
printf("write open succse\n");
return 0 ;
}
编译后单方面程序运行将会导致阻塞,只有两程序都运行才能使程序结束。
两程序互相通信
-
读取端
- 创建命名管道
- 以读的方式打开命名管道
- 使用read()函数读取数据
- 关闭管道
-
写入端
- 以写的方式打开命名管道
- 使用write()函数将数据写入管道
- 关闭管道
示例:
- 读取端
#include <sys/types.h>
#include <sys/stat.h>
#include<stdio.h>
#include<errno.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int nread = 0;
char buf[1024] = {0};
if(mkfifo("./file",0600) == -1 && errno != EEXIST)
{
printf("make fifo defult\n");
perror("why");
}
int fd = open("./file",O_RDONLY);
printf("open succse\n");
while(1)
{
nread = read(fd,buf,30);
printf("read %d byte from fifo\ncontext:%s\n",nread,buf);
}
close(fd);
return 0;
}
- 写入端
#include <sys/stat.h>
#include<stdio.h>
#include<errno.h>
#include <fcntl.h>
#include <unistd.h>
#include<string.h>
int main()
{
int cnt = 0;
char *str = "message from fifo";
int fd = open("./file",O_WRONLY);
printf("write open succse\n");
while(1){
write(fd,str,strlen(str));
sleep(1);
}
close(fd);
return 0;
}