当创建命名管道(FIFO)时,你可以使用两种不同的方法:使用终端命令 mkfifo
或使用编程语言提供的 mkfifo()
函数。
1.使用终端命令 mkfifo
:
-
打开终端或命令行界面。
-
使用以下语法执行
mkfifo
命令来创建一个命名管道:
mkfifo <管道名称>
其中,<管道名称>
是你想要指定的命名管道的名称。
- 例如,要创建一个名为
myfifo
的命名管道,你可以运行以下命令:
mkfifo myfifo
执行上述命令后,将在当前目录中创建一个名为 myfifo
的命名管道文件。
2.使用编程语言提供的 mkfifo()
函数:
- 如果你使用的是编程语言(如C、C++等),可以使用相应的函数来创建命名管道。
- 在 C 语言中,你可以使用
mkfifo()
函数来创建命名管道。该函数定义在<sys/stat.h>
头文件中,并具有以下原型:
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
pathname
参数是要创建的命名管道的路径和名称。mode
参数是权限模式,用于设置管道的权限。一般可以使用0666
(即读写权限)作为参数。- 调用
mkfifo()
函数将在指定路径创建一个命名管道。 - 以下是一个使用
mkfifo()
函数创建名为myfifo
的命名管道的示例:
#include <sys/stat.h>
int main() {
const char *fifoPath = "myfifo";
mode_t fifoMode = 0666;
int result = mkfifo(fifoPath, fifoMode);
if (result == 0) {
printf("FIFO created successfully.\n");
} else {
printf("Failed to create FIFO.\n");
}
return 0;
}
创建命名管道后会出现管道文件:
以下是使用命名管道的一般步骤:
-
创建命名管道:可以使用
mkfifo
命令或mkfifo()
函数创建命名管道。例如,使用终端命令创建一个名为myfifo
的命名管道:mkfifo myfifo
-
打开命名管道:在进程中打开命名管道以进行读取或写入操作。在 C 语言中,你可以使用
open()
函数来打开管道。例如,要在一个进程中打开命名管道以进行写入操作:int fd = open("myfifo", O_WRONLY);
,在另一个进程中打开命名管道以进行读取操作:int fd = open("myfifo", O_RDONLY);
-
读取和写入数据:使用打开的文件描述符
fd
进行数据的读取和写入。对于写入操作,你可以使用write()
函数向管道写入数据,对于读取操作,你可以使用read()
函数从管道中读取数据。这些操作可以在不同的进程中执行。 -
关闭命名管道:当进程完成读取或写入操作后,应该关闭命名管道。使用
close()
函数关闭文件描述符即可。 -
删除命名管道:当不再需要命名管道时,可以使用
unlink()
函数或终端命令rm
删除该管道。例如,使用终端命令删除名为myfifo
的命名管道:rm myfifo
请注意,命名管道是阻塞的,这意味着如果没有进程等待读取管道中的数据,写入操作将被阻塞,直到有进程开始读取数据。同样地,如果没有进程写入数据到管道中,读取操作将被阻塞,直到有数据可供读取。
使用命名管道时,需要确保相关进程以正确的顺序进行打开、读取和写入操作,以避免出现死锁或其他问题。
案例:
fifo_w.c用于向管道中写入数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>
void sys_err(const char* str)
{
perror(str);
exit(1);
}
int main(int argc, char* argv[])
{
int fd,i;
char buf[4096];
if(argc < 2)
{
printf("Enter like this :./a.out fifoname\n");
return -1;
}
fd = open(argv[1],O_WRONLY);
if(fd<0)
{
sys_err("open error!");
}
i=0;
while(1)
{
sprintf(buf,"hello itcast %d\n",i++);
write(fd,buf,strlen(buf));
sleep(1);
}
close(fd);
return 0;
}
fifo_r.c用于向管道中读数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>
void sys_err(const char* str)
{
perror(str);
exit(1);
}
int main(int argc, char* argv[])
{
int fd,len;
char buf[4096];
if(argc<2)
{
printf("./a.out fifoname\n");
return -1;
}
fd = open(argv[1],O_RDONLY);
if(fd<0)
sys_err("open error");
while(1)
{
len=read(fd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,len);
sleep(3);
}
close(fd);
return 0;
}
注意:fifo可以有多个写端一个读端,但是不可以有一个写端多个读端,因为管道里的数据经过一次读取后就消失了。