有名管道
在创建管道成功之后,就可以使用open()、read()和write()这些函数了。与普通文件的开发设置一样,对于为读而打开的管道可在open()中设置O_RDONLY,对于为写而打开的管道可在open()中设置O_WRONLY,在这里与普通文件不同的是阻塞问题。
由于普通文件的读写时不会出现阻塞问题,而在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open()函数中设定为O_NONBLOCK。
对于O_RDONLY、 O_WRONLY、 O_NONBLOCK有4种组合方式:
1、open(const char *path,O_RDONLY)
在这种情况下,open 调用将阻塞,除非有一个进程以写方式打开同一个FIFO,否则它不会返回
2、open(const char *path,O_RDONLY|O_NONBLOCK )
即使没有其它进程以写方式打开FIFO,这open调 用也将成功并马上返回
3、open(const char *path,O_WRONLY)
open调用将阻塞,直到有一个进程以读方式打开同一个 FIFO为止。
4、open(const char *path,O_WRONLY|O_NONBLOCK )
open调用总是立刻返回,便如果没有进程以读方式打开FIFO文件, open调用将返回一个错误(-1)并且FIFO也不会被打开。
对于读进程
• 若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入。
• 若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。
对于写进程
• 若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入。
• 若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败。
例子:
读进程:(fifoRead.c)运行需要在root用户下
#include<unistd.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #include<stdio.h> #include<stdlib.h> int main() { if(mkfifo("/tmp/fifo1",O_CREAT|O_EXCL)==-1) printf("mkfifo fail...");//第二次会输出该结果,因为之前创建了。 int fd = open("/tmp/fifo1",O_RDONLY);//O_WRONLY,O_WRRD.... char buf[1024]; memset(buf,'\0',sizeof(buf)); if ( fd == -1) { printf("open fail..."); } else { read(fd,buf,sizeof(buf)); printf("buf is %s\n",buf); } return 0; }
写进程(fifoWrite.c):(读进程和写进程是2个进程,所以需要在2个终端分别运行)
#include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> int main() { int fd = open("/tmp/fifo1",O_WRONLY);//O_WRONLY,O_WRRD.... if ( fd == -1) { printf("OPEN fail..."); } else { write(fd,"123",3); } return 0; }