作者:李慧芹,华清远见嵌入式学院讲师。
区别于无名管道,命名管道可以用于没有亲缘关系的进程之间进行通信,且命名管道在一些特点上更类似于文件,其具有文件名,文件属性及存放路径等信息,也就是说利用命名管道进行操作后,我们可以在相应的路径下查找到它,更方便编程的需要和操作,且命名管道严格地遵循先进先出原则。
命名管道在创建成功后,就可以与普通文件的开发设置一样了,下面通过一个例子我们来说明一下命名管道的使用及注意事项,假设情境:我们需要两个进程进行数据的交换,那么创建命名管道后,一个进程负责向管道内写入数据,另一个进程负责由管道读出数据。代码段如下:
//写端代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int ret;
int fd;
ret=mkfifo("fifo",0644); //创建命名管道
if(ret<0) //管道是否创建成功,不成功则退出程序
{
perror("fifo error\n");
exit(-1);
}
fd = open("fifo",O_WRONLY); //打开管道文件
if(fd<0) //打开是否成功,不成功则退出程序
{
perror("open error\n");
exit(-1);
}
write(fd,"hello",6); //进行写端操作
close(fd);
unlink("fifo"); //删除命名管道 *
return 0;
}
//读端代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd;
char str[20];
fd = open("fifo",O_RDONLY); //打开管道文件
if(fd<0) //打开是否成功,不成功则退出
{
perror("open error\n");
exit(-1);
}
read(fd,str,sizeof(str)); //进行读取操作
printf("%s\n",str); //将读取到的数据进行打印输出
close(fd);
return 0;
}
上述两个程序分别编译链接成可执行程序,且同时运行于2个终端上,进行执行效果的观察。
命名管道在使用时,需要尤其注意以下3点,大家可以对照上面的程序段体会:
1、管道创建成功后,可以像操作普通文件一样进行操作,但是,两个进程打开一个命名管道的时候,必须分别以”只“的方式打开,且必须相反,即一个进程以只读方式打开,另一进程以只写方式打开。
2、在终端上单独运行写端程序时,会发现,终端无任何反应,而读端程序一旦开始运行,则两个程序同时结束,说明命名管道只打开一端的话是无法成功的,此时open是无法正常返回的,也就是说管道两端需要同时打开,这也是命名管道的一个特点。
3、写端代码中标记为“*”的语句作用为删除命名管道,可将该句暂时注释掉,则在程序结束后,可在当前路径下可以找到一个名为“fifo”的文件,且其文件属性为“p”,为管道类型文件,这也是区别于无名管道的一大特点,使用结束后可以找到具体文件,所以命名管道是可以应用于无亲缘关系的进程间的。
另外,在创建管道的时候,如果指定路径下存在一个与命名管道同名的文件,则编译器提示命名管道未创建成功,为避免后期使用出现问题,通常在使用命名管道后予以删除操作。
文章评论(0条评论)
登录后参与讨论