我要努力工作,加油!

linux c语言编程,使用mkfifo创建FIFO特殊文件,用于进程间通信

		发表于: 2018-10-18 19:58:24 | 已被阅读: 27 | 分类于: C语言
		

使用

mkfifo
创建一个
FIFO
特殊文件,可用于进程间通信。这种特殊文件,不占磁盘空间,但是可以像普通文件一样读写。

mkfifo 函数简介

mkfifo 的原型和所需头文件如下:

#include <sys/types.h>
#include <sys/stat.h>

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

mkfifo 的返回值

成功返回 0,失败返回 -1,失败码可从

errno
查询。

mkfifo 功能

mkfifo()
函数创建一个名为 pathname 的
FIFO
特殊文件,mode 参数用于指定权限。创建的
FIFO
特殊文件与管道是类似的,都可以用于进程间通信。这种特殊的
FIFO
文件可以被文件系统加载,因此可以像普通文件一样读写和删除。

使用

mkfifo
函数创建了
FIFO
特殊文件后,任何进程都可以像普通文件一样打开之,并读写。通常,读取
FIFO
特殊文件会被阻塞,直到有进程写入数据到
FIFO
文件。

mkfifo 函数的简单使用 demo

以下的 demo,首先创建了一个

FIFO
特殊文件,然后
fork
出一个子进程。父进程延时1秒后,往
FIFO
文件写入 "
https://blog.popkx.com\n
",然后使用
waitpid
函数等待子进程结束。子进程则从
FIFO
文件读取数据,并且将读出的数据打印到终端。

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

#define FIFO       "blog_popkx_com"

int main()
{
    char buffer[80];
    int fd;
    char s[] = "https://blog.popkx.com\n";

    unlink(FIFO);
    mkfifo(FIFO, 0666);

    switch(fork())
    {
        case -1: 
            printf("fork failed\n"); 
            break;
        case 0:
            fd = open(FIFO, O_RDONLY);
            int len = read(fd, buffer, 80);
            printf("\nlen: %d, %s\n", len, buffer);

            close(fd);
            break;
        default:
            sleep(1);
            fd = open(FIFO, O_WRONLY);
            write(fd, s, sizeof(s));
            close(fd);

            int childRet = 0;
            waitpid(-1, &childRet, 0);

            unlink(FIFO);
            break;
    }

    return 0;
}

编译之,执行结果如下:

$ gcc fifo.c 
$ ./a.out 

len: 24, https://blog.popkx.com

子进程的读取操作被阻塞,直到父进程往

FIFO
特殊文件写入数据,子进程才从中读出数据,并且打印到终端。

对 FIFO 特殊文件的进一步测试

在子进程中加入延时,如下:

...
 switch(fork())
    {
        case -1: 
            printf("fork failed\n"); 
            break;
        case 0:
            sleep(10);      //  加入适当延时,便于其他测试
            fd = open(FIFO, O_RDONLY);
            int len = read(fd, buffer, 80);
            printf("\nlen: %d, %s\n", len, buffer);
...

这样一来,就会有一段时间

FIFO
文件里有父进程写入的数据,而子进程还没有将之读出。我们在这段时间里,先查看其占用磁盘空间:

$ ls -ahl
total 24K
drwxrwxr-x  2 lcc lcc 4.0K 10月 18 19:50 .
drwxrwxr-x 14 lcc lcc 4.0K 10月 18 18:50 ..
-rwxrwxr-x  1 lcc lcc 9.0K 10月 18 19:50 a.out
prw-rw-r--  1 lcc lcc    0 10月 18 19:50 blog_popkx_com          # 占用磁盘空间为 0
-rw-rw-r--  1 lcc lcc  754 10月 18 19:50 fifo.c
$ 
$ 
$ cat blog_popkx_com 
https://blog.popkx.com

但是可以使用

cat
命令将
FIFO
文件中的内容读出。接着,发现进程一直阻塞,这是因为
FIFO
文件中的内容为空了,子进程的读取操作会一直阻塞到别的进程再往
FIFO
文件写入内容,才会返回,并且将其中的内容读出。而父进程则会一直 wait 到子进程返回。

$ ps -a|grep a.out
 59923 pts/19   00:00:00 a.out
 59924 pts/19   00:00:00 a.out