在使用有名管道(Named Pipe,FIFO)时,返回的文件描述符 3 和 4 是通过 open()
系统调用打开有名管道后分配的文件描述符。文件描述符是进程用来访问打开的文件或管道的整数标识符。
1. 文件描述符的分配规则
-
文件描述符是一个非负整数,通常是当前进程未使用的最小整数。
-
默认情况下,每个进程已经打开了三个标准的文件描述符:
-
0
:标准输入(stdin) -
1
:标准输出(stdout) -
2
:标准错误(stderr)
-
-
因此,当进程第一次打开一个文件或管道时,通常会分配文件描述符 3,第二次打开时会分配 4,依此类推。
2. 有名管道返回 3 和 4 的场景
假设一个进程通过 open()
系统调用两次打开同一个有名管道:
int fd1 = open("/tmp/my_fifo", O_RDONLY); // 返回 3
int fd2 = open("/tmp/my_fifo", O_WRONLY); // 返回 4
-
第一次调用
open()
时,返回的文件描述符是 3,因为 0、1、2 已经被标准输入、输出和错误占用。 -
第二次调用
open()
时,返回的文件描述符是 4,因为 3 已经被第一次调用占用。
3. 文件描述符的作用
-
文件描述符是进程与内核之间的桥梁,用于标识打开的文件、管道、套接字等。
-
在有名管道的场景中:
-
文件描述符 3 可以用于从管道读取数据(如果以
O_RDONLY
模式打开)。 -
文件描述符 4 可以用于向管道写入数据(如果以
O_WRONLY
模式打开)。
-
4. 示例代码
以下是一个使用有名管道的示例代码,展示了文件描述符的分配和使用:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
// 创建有名管道
mkfifo("/tmp/my_fifo", 0666);
// 打开有名管道(读取端)
int fd1 = open("/tmp/my_fifo", O_RDONLY);
printf("Opened FIFO for reading, fd = %d\n", fd1);
// 打开有名管道(写入端)
int fd2 = open("/tmp/my_fifo", O_WRONLY);
printf("Opened FIFO for writing, fd = %d\n", fd2);
// 写入数据
char *msg = "Hello, FIFO!";
write(fd2, msg, 13);
printf("Data written to FIFO\n");
// 读取数据
char buf[128];
read(fd1, buf, sizeof(buf));
printf("Data read from FIFO: %s\n", buf);
// 关闭文件描述符
close(fd1);
close(fd2);
// 删除有名管道
unlink("/tmp/my_fifo");
return 0;
}
5. 总结
-
有名管道返回的文件描述符 3 和 4 是通过
open()
系统调用分配的。 -
文件描述符是进程访问有名管道的标识符,用于读写操作。
-
文件描述符的分配遵循最小可用整数的规则,通常从 3 开始(因为 0、1、2 已被标准输入、输出和错误占用)。