FIFO

FIFO(first in, first out)。每个fifo与路径名有关,从而允许无亲缘关系的进程访问同一个FIFO。

#include <sys/types.h>

#include <sys/stat.h>

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

注意:

mkfifo已经已经隐含指定O_CREAT | O_EXCL,这就会导致要么创建一个新的fifo文件,要么就会返回一个EEXIT错误。

FIFO不能打开来既是读也是写,因为它是半双工的。

read总是从开头开始读,write总是往末尾写。

如果用了lseek函数,则会返回错误ESPIPE。

要删除一个fifo文件用函数unlink()。

例子:重写管道一中的客户--服务器程序,用两个FIFO代替两个管道。

代码:

//mainfifo.c 
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>

#define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)//FIFO文件打开权限
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"



void client(int, int),server(int, int);

int main(int argc, char **argv)
{
    pid_t childfd;
    int readfd, writefd;
    char buff[20];

    if ((mkfifo(FIFO1, FILEMODE) < 0) && (errno != EEXIST)) {//创建FIFO1文件,如果已经存在报错,不处理。
        snprintf(buff, sizeof(buff), "can't create %s\n", FIFO1);
        perror(buff);
    }

    if ((mkfifo(FIFO2, FILEMODE) < 0) && (errno != EEXIST)){//创建FIFO1文件,如果已经存在报错,不处理。

        snprintf(buff, sizeof(buff), "can't create %s\n", FIFO2);
        perror(buff);
        unlink(FIFO1);
    }
    
    if ( (childfd = fork()) == 0) {//子进程
        readfd = open(FIFO1, O_RDONLY, 0);//以只读模式打开FIFO1
        writefd = open(FIFO2, O_WRONLY, 0);//以只写模式打开FIFO2
        server(readfd, writefd);//从第一个参数获取文件路径名,然后打开此文件,并将文件内容写入第二个参数中去。
        exit(0);
    }
    /*父进程*/
    writefd = open(FIFO1, O_WRONLY, 0);//以只写模式打开FIFO1
    readfd = open(FIFO2, O_RDONLY, 0);//以只读模式打开FIFO2

    client(readfd, writefd);//从标准输入里读取文件路径名,然后将其写入第二个参数中去,
                             //同时从第一个参数中获取服务器端返回的文件内容,并将其输出到标准输出里
    waitpid(childfd, NULL, 0);
    
    close(readfd);
    close(writefd);

    unlink(FIFO1);//删除掉FIFO文件
    unlink(FIFO2);

    exit(0);
}

你可能感兴趣的:(FIFO)