管道-fifo

来源:互联网 发布:红色复仇软件破解版 编辑:程序博客网 时间:2024/05/01 19:16

一. 简介

    FIFO 又称为 named pipe、命名管道,用于在不相关的进程之间传递数据,可以通过命令行创建:

        mkfifo filename

    也可以通过程序创建:

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

    此外,还可以利用 mknod,但该命令非规范。


二. 实质

    FIFO 是磁盘上一个真实的文件,可以像删除普通文件那样,在命令行用 rm 删除,在程序中用 unlink 删除。

    使用 ls 查看结果如下:

        prwxrwxrwx 1 rick users 0 XXXX-XX-XX XX:XX /named-pipe|

    输出结果中第一个字符为 p,最后一个字符为 |。


三. 深入

    FIFO 使用 open 和 close 打开和关闭(底层 IO 库的使用场景,虽然它们并不是 ANSI C 的一部分)。其最重要的内容,就是 open 操作。

1. 使用 open 打开 FIFO 时,不能使用 O_RDWR 模式,因为管道是单向的,如果被以读/写的方式打开,进程就会从这个管道读回它自己的输出。

2. 打开 FIFO 和打开普通文件的区别,在于对 open_flag 的O_NONBLOCK 选项的用法。有以下 4 种组合:

    open(const char *path, O_RDONLY);

    该模式下,open 调用将阻塞。当另一个进程以写方式打开同一个 FIFO 后,两个程序继续运行。读进程和写进程在 open 调用处取得同步。

    open(const char *path, O_WRONLY);

    此时 open 调用同样将阻塞,直到另一个进程以读方式打开同一个 FIFO。

    open(const char *path, O_RDONLY | O_NONBLOCK);

    即使没有其它进程以写方式打开该 FIFO,该 open 调用也将成功并立即返回。总是成功

    open(const char *path, O_WRONLY | O_NONBLOCK);

    该调用总是立即返回。如果已经有一个进程以读方式打开 FIFO,那么可以通过其返回的文件描述符操作该 FIFO。但如果没有进程以读方式打开 FIFO,该调用将返回 -1 错误。如果没有以读方式打开,则失败,如果已经以读方式打开,则成功

3. O_NONBLOCK 对读写的影响

    对一个空的、阻塞的 FIFO(即没有用 O_NONBLOCK 方式打开) 的 read 调用将等待,直到有数据可以读时才继续进行。与此相反,对一个空的、非阻塞的 FIFO 的 read 调用将立刻返回 0。

    对一个完全阻塞的 FIFO 的 write 调用将等待,直到数据可以写入。

    即阻塞/非阻塞的原始含义

4. FIFO 的长度

    系统对任一时刻在一个 FIFO 中可以存在的数据长度是有限制的,由 #define PIPE_BUF 定义,通常在 limits.h 文件中,一般为 4096。系统规定:在一个以 O_WRONLY 方式打开的 FIFO 中,如果写入的数据长度小于等于 PIPE_BUF,那么或者写入全部字节,或者一个字节都不写入。如果写入的数据长度大于 PIPE_BUF,将可能写入部分数据并返回写入的字节数,也可能无法写入任何数据,返回 0。

5. 竞争

    如果同时有多个进程往一个 FIFO 中写,此时必须保证数据不相互交错或者覆盖。 FIFO 的机制可以保证不覆盖,在一个 PIPE_BUF 范围内也不会交错,唯一的问题是,多个 PIPE_BUF 之间有可能交错。系统确保,如果所有的写请求是发往一个阻塞的 FIFO,并且每个写请求的数据长度小于等于 PIPE_BUF 字节,那么数据就不会交错在一起。


四. 思考

1. 做过测试:读写进程分别打开 FIFO 后,在写进程 write() 成功、读进程尚未 read() 之前,发现磁盘上的 FIFO 大小仍然为 0。考虑到底层的文件操作并没有 flush() 命令,即使 close(),也不会做类似 flush() 的操作,因此,磁盘上的 FIFO 大小,是否一直为 0?也即,虽然可以把 FIFO 视为磁盘文件,但其实质并不是?

2. 关于 三 中的 4、5 两点,前提都是阻塞的 FIFO。对于非阻塞的情况都没有提到,那么,非阻塞的 FIFO 是什么情况?同时,是不是意味着,建议使用阻塞方式而不是非阻塞方式?

原创粉丝点击