一、概述
Linux系统是一个以文件为中心的操作系统,它提供了良好的文件读写接口,在实现不同进程间通信时,也可以使用文件进行通信。Linux中的mkfifo就是为实现不同进程间通信提供的一种接口。mkfifo接口可以用于创建一个特殊的文件,这个文件可以被不同的进程进行读写操作,以实现不同进程间的通信。mkfifo即可创建无名管道(也称FIFO),也可创建有名管道。其中,无名管道只能用于具有亲缘关系的进程间通信,而有名管道可供任何进程使用。
二、创建有名管道
创建有名管道时,可使用系统命令mkfifo,也可使用C语言函数mkfifo,下面是一段示例代码:
#include<stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main()
{
int fd;
char *fifo = "/tmp/myfifo";
mkfifo(fifo, 0666);
fd = open(fifo, O_WRONLY);
write(fd, "Hello World!", 13);
close(fd);
return 0;
}
代码中首先使用mkfifo函数创建了一个名字为/tmp/myfifo
的管道文件,权限为0666。然后使用open函数打开这个管道文件,使用write函数向管道中写入数据,最后关闭管道文件。
三、创建无名管道
创建无名管道时,需要使用系统函数pipe,下面是一段示例代码:
#include<stdio.h>
#include <unistd.h>
int main()
{
int fd[2];
pid_t pid;
char buf[1024];
if(pipe(fd) < 0)
printf("pipe error!\n");
if((pid = fork()) < 0)
printf("fork error!\n");
else if(pid == 0) // child process
{
close(fd[0]);
write(fd[1], "Hello World!", 13);
exit(0);
}
else // parent process
{
close(fd[1]);
read(fd[0], buf, 1024);
printf("message: %s\n", buf);
waitpid(pid, NULL, 0);
}
return 0;
}
代码中首先使用pipe函数创建了一个无名管道,并将管道的读写端分别保存在fd
数组中。然后使用fork函数创建一个子进程,在子进程中通过写操作向管道中写入数据。在父进程中,则通过读操作从管道中读取数据,并输出到终端。
四、mkfifo的局限性
mkfifo虽然可以方便地实现进程间通信,但也存在一定的局限性。一方面,无名管道只能用于有亲缘关系的进程间通信,而且,在写操作和读操作的不同进程不同时运行时,可能会发生进程阻塞的状况;另一方面,使用有名管道时,需要使用FIFO文件,而这会导致文件系统中会存在比较多的FIFO文件,而不同的FIFO文件之间并没有进行有效的区分,难以进行有效的管理和维护,因此在某些情况下并不适合使用。