管道-命名管道(FIFO)

命名管道(FIFO)和管道(pipe)基本相同,但也有一些不同的地方:

1)FIFO在文件系统中作为一个特殊的文件而存在,但FIFO中的内容却存放在内存中。(某个目录下有一个文件名)

2)当使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便以后使用。

3)FIFO有名字,不相关的进程可以通过打开命名管道进行通信。

FIFO文件的创建

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char * pathname, mode_t mode);

参数:pathname是FIFO的路径名+文件名;mode是mode_t类型的权限描述符。

返回值:成功返回0;失败返回-1(如果文件已经存在会失败).

注意:不能用touch命令或者新建文件的方式来创建命名管道。

命名管道必须用特殊的函数mkfifo来创建。

操作FIFO文件时的特点:系统调用的I/O函数都可以作用于FIFO,如open、close、read、write等。

1)未指定O_NONBLOCK(即是阻塞的方式)时,默认是阻塞的

---- 当open以只读方式打开FIFO时,要阻塞到某个进程为写而打开此FIFO。

---- 当open以只写方式打开FIFO时,要阻塞到某个进程为读而打开此FIFO。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char * argv[])
{
        int fd;
        int ret;
        ret = mkfifo("my_fifo",S_IRUSR|S_IWUSR);
        if(ret != 0){
                perror("mkfifo");
        }
        printf("before open.\n");
        fd = open("my_fifo",O_RDONLY);
        if(fd < 0){
                perror("open file.");
        }
        printf("after open.\n");
}

输出如下:


默认情况下,open是带阻塞的,必须有另外一个进程以只写的方式打开也行,所以只输出一行。

即不指定O_NONBLOCK时,open,read,write都是带阻塞的。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char * argv[])
{
        int fd;
        int ret;
        ret = mkfifo("my_fifo",S_IRUSR|S_IWUSR);
        if(ret != 0){
                perror("mkfifo");
        }
        printf("before open.\n");
        fd = open("my_fifo",O_RDONLY|O_NONBLOCK);
        if(fd < 0){
                perror("open file.");
        }
        printf("after open.\n");
}

输出:


---- 当open以只读、只写方式打开FIFO时会阻塞,调用read函数从FIFO里读数据时read也会阻塞。

---- 通信过程中若写进程先退出了,则调用read函数从FIFO中读数据时不阻塞;若写进程又重新运行,则调用read函数从FIFO里读数据时又恢复阻塞。

---- 通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。

---- 调用write函数向FIFO里写数据,当缓冲区已满时,write也会阻塞。

2)打开FIFO时,设置非阻塞标志O_NONBLOCK

---- 先以只读方式打开:如果没有进程已经为写而打开一个FIFO,只读open成功,并且open不阻塞。

---- 先以只写方式打开:如果没有进程已经为读而打开一个FIFO,只写open将出错返回-1.

---- read、write读写命名管道中读数据时不阻塞。

(读时管道中有数据直接读,无数据出错;写时管道没有满可以直接写,如果管道满了,写出错)

---- 通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。

fifo_read_5.c如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char * argv[])
{
        int fd;
        int ret;
        ret = mkfifo("my_fifo",S_IRUSR|S_IWUSR);
        if(ret != 0){
                perror("mkfifo");
        }
        printf("before open.\n");
        fd = open("my_fifo",O_RDONLY|O_NONBLOCK);
        if(fd < 0){
                perror("open file.");
        }
        while(1){
                char recv[100];
                bzero(recv,sizeof(recv));
                read(fd,recv,sizeof(recv));
                printf("read from my_fifo buf = [%s]\n",recv);
                sleep(1);
        }
        return 0;
}

fifo_write_5.c如下

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char * argv[])
{
        int fd;
        char wr[100] = "hello my name is carie.";

        fd = open("my_fifo",O_WRONLY|O_NONBLOCK);
        if(fd < 0){
                perror("open fifo.");
                return 0;
        }
        while(1){
                write(fd,wr,strlen(wr));
                printf("write to my_fifo buf = %s\n",wr);
                sleep(1);
        }
        return 0;
}

编译执行结果:先运行read,后运行write,当read这边用ctrl+c结束后,write端也会自动结束。



Semantically, a FIFO is similar to a pipe. The principal difference is that a FIFO has a name within the file system and is opened in the same way as a regular file. This allows a FIFO to be used for communication between unrelated processes.(e.g a client and server) Just as with pipes, a FIFO has a write end and a read end, and data is read from the pipe in the same order as it is written. This fact gives FIFOs their name: first in, first out. FIFOs are also sometimes known as named pipes.

we can create a FIFO from the shell using the mkfifo command:

$ mkfifo [-m mode] pathname

The pathname is the name of the FIFO to be created, and the -m option is used to specify a permission mode in the same way as for the chmod command.


Generally, the only sensible(合乎情理的) use of a FIFO is to have a ready process and a writing process on each end. Therefore, by default, opening a FIFO for reading (the open() O_RDONLY flag) blocks until another process opens the FIFO for writing (the open() O_WRONLY flag). Conversely(相反地), opening the FIFO for writing blocks until another process opens the FIFO for reading.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值