什么是进程的文件描述符File Descriptors?其创建回收和生命周期

best 365官网体育投注 2025-08-09 02:50:46 admin 961 707
什么是进程的文件描述符File Descriptors?其创建回收和生命周期

在 Linux 和 Unix 系统中,文件描述符(File Descriptor,FD) 是进程用于访问文件、管道、套接字、设备等的一种抽象标识符。本质上,它是一个非负整数,用于标识进程打开的文件或 I/O 资源。

1. 什么是文件描述符?

什么是进程的文件描述符(File Descriptors)?

每个进程都有一个文件描述符表,存储该进程打开的所有文件或 I/O 资源。

文件描述符是进程级别的,每个进程都有自己独立的描述符表。

文件描述符从 0 开始分配,默认有三个标准输入/输出/错误:

文件描述符

名称

作用

默认设备

0

标准输入(stdin)

读取输入数据

键盘

1

标准输出(stdout)

输出正常信息

终端

2

标准错误(stderr)

输出错误信息

终端

2. 文件描述符的生命周期

一个文件描述符的生命周期包括:

分配:进程使用 open()、socket()、pipe() 等系统调用打开文件或资源,系统返回一个文件描述符。

使用:进程通过 read()、write()、send()、recv() 等操作读写文件描述符指向的资源。

关闭:进程调用 close(fd) 释放文件描述符,防止资源泄漏。

3. 文件描述符的创建

(1) open() 打开文件

1234567891011121314

#include <fcntl.h>#include <unistd.h>#include <stdio.h> int main() { int fd = open("test.txt", O_RDONLY); // 以只读模式打开文件 if (fd == -1) { perror("open failed"); return 1; } printf("File Descriptor: %d\n", fd); close(fd); return 0;}

open() 返回的 fd 是进程打开的文件描述符。

close(fd) 关闭文件,释放描述符。

(2) dup() 和 dup2() 复制文件描述符

dup(fd):复制文件描述符,返回新的 FD,指向相同的文件。

dup2(old_fd, new_fd):将 new_fd 复制为 old_fd 的副本。

123456789101112

#include <unistd.h>#include <fcntl.h>#include <stdio.h> int main() { int fd = open("test.txt", O_RDONLY); int new_fd = dup(fd); // 复制文件描述符 printf("Original FD: %d, New FD: %d\n", fd, new_fd); close(fd); close(new_fd); return 0;}

4. 文件描述符的使用

4.1) 标准输入/输出重定向

">" 标准输出重定向

1

echo "Hello World" > output.txt

">" 使 stdout(文件描述符 1)指向 output.txt,不会输出到终端。

"<" 标准输入重定向

1

wc -l < input.txt

"<" 让 stdin(文件描述符 0)从 input.txt 读取,而不是键盘输入。

2> 标准错误重定向

1

ls non_existing_file 2> error.log

2> 让 stderr(文件描述符 2)写入 error.log,不会输出到终端。

&> 同时重定向 stdout 和 stderr

1

command &> output.log

&> 让 stdout 和 stderr 都写入 output.log。

4.2) pipe() 创建管道

123456789101112131415161718192021

#include <unistd.h>#include <stdio.h> int main() { int fd[2]; // fd[0] 读端, fd[1] 写端 pipe(fd); if (fork() == 0) { close(fd[0]); // 子进程关闭读端 write(fd[1], "Hello", 5); close(fd[1]); } else { close(fd[1]); // 父进程关闭写端 char buffer[10]; read(fd[0], buffer, 5); buffer[5] = '\0'; printf("Received: %s\n", buffer); close(fd[0]); } return 0;}

pipe(fd) 创建管道,返回 fd[0](读端)和 fd[1](写端)。

进程通过 read(fd[0]) 读取数据,write(fd[1]) 发送数据。

5. 文件描述符的查看

5.1) ls -l /proc//fd/

1

ls -l /proc/$(pgrep bash)/fd/

查看进程的所有文件描述符。

5.2) lsof 查看进程打开的文件

1

lsof -p $(pgrep bash)

列出 bash 进程打开的所有文件。

5.3)fuser 查看占用文件的进程

1

fuser test.txt

列出访问 test.txt 的所有进程。

6. 文件描述符的限制

6.1) 查看系统允许的最大文件描述符

12

ulimit -n # 查看单个进程最大文件描述符数cat /proc/sys/fs/file-max # 查看系统级最大文件描述符数

6.2) 临时修改文件描述符限制

1

ulimit -n 100000

6.3) 永久修改文件描述符限制

6.3.1) 修改 /etc/security/limits.conf

12

echo "* soft nofile 100000" >> /etc/security/limits.confecho "* hard nofile 200000" >> /etc/security/limits.conf

6.3.2) 修改 /etc/pam.d/common-session

1

echo "session required pam_limits.so" >> /etc/pam.d/common-session

6.3.3) 修改 /etc/systemd/system.conf

1

echo "DefaultLimitNOFILE=100000" >> /etc/systemd/system.conf

7. 文件描述符的回收

进程终止时,操作系统会自动关闭所有打开的文件描述符。

手动回收:使用 close(fd) 释放文件描述符,防止文件描述符泄漏(FD Leak)。

1234567891011121314

#include <fcntl.h>#include <unistd.h>#include <stdio.h> int main() { int fd = open("test.txt", O_RDONLY); if (fd == -1) { perror("open failed"); return 1; } // 进行文件操作 close(fd); // 关闭文件,避免文件描述符泄漏 return 0;}

8. 理解文件描述符对编写高效的 Linux 服务器程序(如 Nginx、Redis) 至关重要

文件描述符是 Linux 进程访问文件、管道、套接字的核心机制。

标准文件描述符(0、1、2)用于输入、输出和错误,可以重定向。

使用 open()、socket()、pipe() 创建文件描述符,close(fd) 释放。

dup() 和 dup2() 复制文件描述符,可用于 I/O 重定向。

使用 ulimit 和 limits.conf 调整文件描述符上限,避免 “Too many open files” 错误。

wer

相关文章:

Linux 进程的详细解释

进程间通信信号(Signals)详解

Linux 进程的构成

Linux系统的构成

linux内核的进程调度策略

Linux系统信息与管理命令清单

必须掌握的 Linux 命令

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

相关推荐

1000克等於幾兩
365bet规则

1000克等於幾兩

07-29 915
百合网怎么收费
365娱乐app官方版下载

百合网怎么收费

07-11 875
手机多屏互动软件排行榜TOP10推荐
365娱乐app官方版下载

手机多屏互动软件排行榜TOP10推荐

07-21 73