有名管道:
管道的一个不足之处是没有名字,因此,只能用于具有 亲缘关系的进程间通信,在有名管道提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存储与文件系统中。有名管道是一个设备文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。值得注意的是,FIFO总是按照先进先出的原则工作,第一个被写入的数据将首先从管道中读出。创建有名管道的系统函数有两个:mknod和mkfifo。两个函数均定义在头文件sys/stat.h,函数原型如下:
#include<sys/types.h>mknod&mkfifo函数参数:
path:有名管道的全路径名;参数值:
“S_IFIFO|0666”指明创建一个有名管道且存取权限为0666,即创建者、与创建者同组的用户、其他用户对该有名管道的访问权限都是可读可写。使用有名管道时,必须先调用open()将其打开。调用open()打开有名管道的进程可能会被阻塞,但如果同时用读写方式(O_RDWR)打开,则一定不会导致阻塞;如果以只读方式(O_RDONLY)打开,则调用open()函数的进程将会被阻塞直到有写方打开管道;同样以写方式(O_WRONLY)打开也会阻塞直到有读方打开管道。
2.示例代码:
使用有名管道在两个无亲缘进程之间通信
procwrite.c
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #define FIFO_NAME "myfifo" #define BUF_SIZE 1024 int main() { int fd; char buf[BUF_SIZE]="Hello procwrite,I come from process named procread!"; umask(0); if(mkfifo(FIFO_NAME,S_IFIFO|0666)==-1) { perror("mkfifo error!"); exit(1); } if((fd=open(FIFO_NAME,O_WRONLY))==-1) { perror("fopen error!"); exit(1); } write(fd,buf,strlen(buf)+1); close(fd); exit(0); }procread.c
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #define FIFO_NAME "myfifo" #define BUF_SIZE 1024 int main() { int fd; char buf[BUF_SIZE]; umask(0); fd=open(FIFO_NAME,O_RDONLY); read(fd,buf,BUF_SIZE); printf("Read content:%s\n",buf); close(fd); exit(0); }
1.先运行procwrite,
pc@ubuntu:~/linux_lan/pipe/10.3$ ./procwrite
再运行procread,
pc@ubuntu:~/linux_lan/pipe/10.3$ ./procread
在procread端得到:
Read content:Hello procwrite,I come from process named procread!
在两个源程序目录下,出现myfifo文件。
PS:再次运行需删除myfifo。