fifo简介

FIFO与管道类似,是一个单向数据流,但由于FIFO与某个路径名关联,允许无亲缘关系的进程访问同一个FIFO进行通信。

创建FIFO

FIFO可由mkfifo函数或命令创建,函数原型如下:

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

说明:

利用FIFO通信示例

回射服务端

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

#define FIFO1 "/tmp/fifo1"
#define FIFO2 "/tmp/fifo2"

int main() {
    int rfd, wfd, len;
    char buf[256];

    if (mkfifo(FIFO1, 0644) < 0 && errno != EEXIST) {
        fprintf(stderr, "create fifo %s failed", FIFO1);
        return 1;
    }
    if (mkfifo(FIFO2, 0644) < 0 && errno != EEXIST) {
        fprintf(stderr, "create fifo %s failed", FIFO2);
        unlink(FIFO1);
        return 1;
    }

    rfd = open(FIFO1, O_RDONLY, 0);
    wfd = open(FIFO2, O_WRONLY, 0);
    while ((len = read(rfd, buf, sizeof(buf))) > 0) {
        write(STDOUT_FILENO, buf, len);
        write(wfd, buf, len);
    }
    close(rfd);
    close(wfd);
    unlink(FIFO1);
    unlink(FIFO2);
    return 0;
}

回射客户端

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

#define FIFO1 "/tmp/fifo1"
#define FIFO2 "/tmp/fifo2"

int main() {
    int rfd, wfd, len;
    char buf[256];

    wfd = open(FIFO1, O_WRONLY);
    rfd = open(FIFO2, O_RDONLY);
    while (fgets(buf, sizeof(buf), stdin)) {
        write(wfd, buf, strlen(buf));
        memset(buf, 0, sizeof(buf));
        len = read(rfd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, len);
    }
    close(wfd);
    close(rfd);
    return 0;
}

注意点:

非阻塞IO设置

将描述符设置成非阻塞有两种方式:

  1. 在调用open时指定O_NONBLOCK标志。
  2. 通过fctnl调用。
int flag = fcntl(fd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(fd, SETFL, flag);

第二种方式更为通用,管道只能以该方式设置成非阻塞。

管道IO特点

关于管道和FIFO的读写,有以下特点:

Table of Contents