第十五章(二) FIFO、消息队列及信号量

来源:互联网 发布:红杉树网络会议系统 编辑:程序博客网 时间:2024/05/17 02:21

FIFO
    FIFO也称为命名管道,没有了未命名管道只能在两个相关进进程之间才能运行的局限性;
    通过FIFO, 两个不相关的进程也能交换数据。

    FIFO是一种文件类型,通过stat结构的 st_mode 成员的编码可以知道文件是否是FIFO类型。 可以用 S_ISFIFO宏对此进行测试。
    创建FIFO类似于 创建文件,路径名是事实存在的。

    函数    int mkfifo(char *path, mode_t mode);
                int mkfifoat(int fd, char *path, mode_t mode);

            mode 参数的规格说明与open函数中mode的相同。

    当我们用mkfifo创建FIFO时,要用open来打开它。
    当open一个FIFO时,非阻塞标志(O_NONBLOCK)会产生以下影响:
        1、在一般情况下(即没有指定O_NONBLOCK),只读open要阻塞到某个其他进程为写而打开这个FIFO为止。 类似的 ,只写open要阻塞到某个其他进程为读而打开它为止
        2、如果指定了O_NONBLOCK,则只读open立即返回。但是,如果没有进程为读而打开一个FIFO,那么只写open将返回-1, 并将errno设置为ENXIO

    类似于管道,若write一个尚无进程为读而打开的FIFO,则产生信号 SIGPIPE。 若某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。

    用途:
        1、shell命令使用FIFO将数据从一条管道传送到另一条管道时,无需创建中间临时文件。
        比如:
            一个程序要将一份经过处理的输入流进行两次处理:

                                                               
            (tee程序将其标准输入同时复制到其标准输出及其命令行中命名的文件中)
            $ mkfifo fifo1
            $ cmd3 < fifo1 &
            $ cmd1 < infile | tee fifo1 | cmd2


                                               
            
        2、客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程之间传递数据。


                                                                         


            
            服务器进程如何将回答送回给各个进程呢。不能使用单个FIFO,因为客户进程不可能知道何时去读它们的响应以及何时响应其他客户进程
            一种解决方案是,每个客户进程都在其请求中包含它的进程ID,然后服务器进程为每个客户进程创建一个FIFO,使用ID为基础的文件名:


                                             

0 0