上篇博客写到了无名管道,但是仅限于父进程和子进程之间;
本片文章介绍有名管道,有名管道和无名管道使用类似,使用的API如下
创建好有名管道后,在使用之前都必须打开管道,在linux中一切都是文件的哲理思想在这里又出现了,
打开的时候可以设置阻塞或者非阻塞,但是有一点需要,当管道两端读写之中有任何一个设置为非阻塞时,必须保证阻塞的那个进程先运行,否则程序会崩溃,这一点也是有名管道使用的难点。本示例演示的是半双工的,有兴趣的可以改成全双工的,代码如下
写进程端
//写进程
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define FIFO_NAME "/tmp/myfifo"
int main()
{
int fd;
char w_buf[50];
int w_num;
// 若fifo已存在,则直接使用,否则创建它
if((mkfifo(FIFO_NAME,0777)<0)&&(errno!=EEXIST))
{
printf("cannot create fifo...\n");
exit(1);
}
//以阻塞型只写方式打开fifo
fd=open(FIFO_NAME,O_WRONLY);
/****阻塞时,open一直未返回,直到另一个进程以只读方式打开fifo****/
printf("%d\n",w_num);
}
读进程端
//有名管道读文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int arg, char *args[])
{if (arg < 2)
{
printf("请输入一个参数!\n");
return -1;
}
int fd = 0;
char buf[100] = { 0 };
//打开管道文件
fd = open(args[1], O_RDONLY);
if (fd == -1)
{
printf("open the file failed ! error message : %s\n", strerror(errno));
return -1;
}
while (read(fd, buf, sizeof(buf)) > 0)
{
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}
//close the file stream
close(fd);
return 0;
}
上面提到的open是阻塞和非阻塞的情况大家可以自由组合下,试下什么效果,阻塞解除的条件就是另外一个进程打开管道时,阻塞的open才会有返回值!