Linux 文件描述符
Posted Vincen_shen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 文件描述符相关的知识,希望对你有一定的参考价值。
File Descriptor - 文件描述符
文件描述符 0 stdin 标准输入
文件描述符 1 stdout 标准输出
文件描述符 2 stderr 标准错误输入
系统为每一个进程维护一个文件描述符表 《文件描述符表》 0 stdin 1 stdout 2 stderr 3 fd-001 --> 文件1 4 fd-002 --> 文件2 ... ... ... 1024 --> Linux默认文件描述符最大值 # ulimit -n 查看文件描述符最大值 # ulimit -HSn 65536 // 临时增大文件描述符数命令 # 永久更改文件描述符最大数:在 /etc/security/limits.conf 文件最后加入如下两行: * soft nofile 65536 * hard nofile 65536
文件描述符(file descriptor)通常是一个小的非负整数,内核用以标识一个特定进程正在访问的文件。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。
每个进程在PCB(Process Control Block)中保存着一份《文件描述符表》,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。
一个进程启动时,都会打开3个文件: stdin stdout stderr
C语言示例
在C语言中可以使用 dup2函数 来复制文件描述符
dup2(int oldfd, int newfd);
dup2用参数newfd指定新文件描述符的数值,若参数newfd已经被程序使用,则系统就会将newfd所指的文件关闭。
若dup2调用成功则返回新的文件描述符,出错则返回-1.
#include <stdio.h> #include <unistd.h> #include <string.h> #include <fcntl.h> int main(){ char input[1024] = "Please Input Information:"; write(1, input, strlen(input)); // 从 文件描述符1(stdout) 写入指定长度内容,将直接在屏幕显示 char buf[1024]; read(0, buf, sizeof(buf)); // 从 文件描述符0(stdin)读取指定长度内容 write(1, buf, strlen(buf)); // 从 文件描述符1(stdout)写入指定长度内容 write(2, buf, strlen(buf)); // 从 文件描述符2(stderr)写入指定长度内容 char* filePath = "./stdout_stderr.txt"; int fd = open(filePath, O_CREAT|O_RDWR, 0664); // 创建一个文件描述符 dup2(fd, 1); // 将 文件描述符fd 复制到 文件描述符1(stdout) execlp("ls", "ls", "-l", NULL); // 执行命令,标准stdout close(fd); // 关闭文件描述符 return 0; }
lsof 是一个列出当前系统打开文件的工具
查询单个进程允许打开的最大FD数量
$ ulimit -n
$ ulimit -a
查询所有进程已打开的FD数量和最大限制数量
$ cat /proc/sys/fs/file-nr
2112 0 2100000
已分配并使用文件句柄数目 / 已分配未使用句柄数目 / 文件句柄最大数目
查看进程已打开的FD
$ ls -l /proc/9700/fd/
lr-x------. 1 mysql mysql 64 12月 10 07:54 0 -> /dev/null
l-wx------. 1 mysql mysql 64 12月 10 07:54 1 -> /var/log/mysqld.log
lrwx------. 1 mysql mysql 64 12月 10 07:54 10 -> /var/lib/mysql/ibdata1
lrwx------. 1 mysql mysql 64 12月 10 07:54 11 -> /var/lib/mysql/ib_logfile1
lrwx------. 1 mysql mysql 64 12月 10 07:54 12 -> /var/lib/mysql/undo_001
lrwx------. 1 mysql mysql 64 12月 10 07:54 13 -> /tmp/#17635842 (deleted)
lrwx------. 1 mysql mysql 64 12月 10 07:54 14 -> /var/lib/mysql/undo_002
lrwx------. 1 mysql mysql 64 12月 10 07:54 15 -> /var/lib/mysql/ibtmp1
lrwx------. 1 mysql mysql 64 12月 10 07:54 16 -> /var/lib/mysql/#innodb_temp/temp_1.ibt
lrwx------. 1 mysql mysql 64 12月 10 07:54 17 -> /var/lib/mysql/#innodb_temp/temp_2.ibt
lrwx------. 1 mysql mysql 64 12月 10 07:54 18 -> /var/lib/mysql/#innodb_temp/temp_3.ibt
lrwx------. 1 mysql mysql 64 12月 10 07:54 19 -> /var/lib/mysql/#innodb_temp/temp_4.ibt
以上是关于Linux 文件描述符的主要内容,如果未能解决你的问题,请参考以下文章
在 Linux 中使用 Qt 的 Close() 文件描述符
Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段