LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 886|回复: 2

今天发现linux下的FIFOs是全双工的管道。

[复制链接]
发表于 2005-2-2 21:12:24 | 显示全部楼层 |阅读模式
看了stevens的UNPv2, 上面说mkfifo打开的管道是half-duplex,今天用O_RDWR的方式打开管道,发现可以同时读写。
源代码如下:
/*
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

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

#define MODE    (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define FIFO    "/tmp/.fifojbug"

int main(void)
{
    int         fd1, fd2;
    ssize_t     n;
    char        buf[10];
    pid_t       cpid;

    if ((mkfifo(FIFO, MODE) < 0) && errno != EEXIST) {
        printf("can't make FIFOs %s", FIFO);
        perror(NULL);
        exit(1);
    }

    if ( (cpid = fork()) < 0) {
        printf("can't fork child\n");
        perror(NULL);
        exit(1);
    }
    else if (cpid == 0) {  /* child process */
        if ( (fd1 = open(FIFO, O_RDWR)) < 0) {
            printf("can't open FIFOs %s with O_RDWR mode\n", FIFO);
            perror(NULL);
            exit(1);
        }

        if (write(fd1, "client", 6) <= 0) {
            printf("child: can't write to fd1\n");
            perror("child");
            exit(1);
        }
        printf("child: write: client\n");

        sleep(1);
        if ( (n = read(fd1, &buf, 10)) != 6) {
            printf("child: can't read from fd1\n");
            perror("child");
            exit(1);
        }
        buf[n] = 0;
        printf("child: read: %s\n", buf);

        exit(0);
    }

    /* parent process */
    if ( (fd2 = open(FIFO, O_RDWR)) < 0) {
        printf("parent: can't open FIFOs %s with O_RDWR mode\n", FIFO);
        perror("parent");
        exit(1);
    }

    if ( (n = read(fd2, buf, 10)) != 6) {
        printf("parent: can't read from fd2\n");
        perror("parent");
        exit(1);
    }
    buf[n] = 0;
    printf("parent: read: %s\n", buf);

    if (write(fd2, "parent", 6) != 6) {
        printf("can't write to fd2\n");
        perror(NULL);
        exit(1);
    }
    printf("parent: write: parent\n");

    waitpid(cpid, NULL, 0);
    unlink(FIFO);

    exit(0);
}
 楼主| 发表于 2005-2-2 21:55:09 | 显示全部楼层
后来仔细想了想,应该不是duplex,因为duplex要求读和写都有缓冲区,而mkfifo产生的管道只有一个缓冲区,只是你可以用读写的方式打开fifo文件。读的和写的都是同一个缓冲区的内容,上面程序中如果去掉sleep语句,父进程可能阻塞在读管道:如果子进程执行完写管道,在父进程之前读管道,子进程执行完了自己的读写任务,父进程开始读管道,由于管道是空的同时管道写端没有关闭(父进程自己开了写端),所以父进程一直阻塞。
回复 支持 反对

使用道具 举报

发表于 2005-2-2 22:19:16 | 显示全部楼层
socketpair可以得到可读写的管道.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表