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

lsof 是一个列出当前系统打开文件的工具 

 

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; }

 

 

查询单个进程允许打开的最大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 1210 07:54 0 -> /dev/null
l-wx------. 1 mysql mysql 64 1210 07:54 1 -> /var/log/mysqld.log
lrwx------. 1 mysql mysql 64 1210 07:54 10 -> /var/lib/mysql/ibdata1
lrwx------. 1 mysql mysql 64 1210 07:54 11 -> /var/lib/mysql/ib_logfile1
lrwx------. 1 mysql mysql 64 1210 07:54 12 -> /var/lib/mysql/undo_001
lrwx------. 1 mysql mysql 64 1210 07:54 13 -> /tmp/#17635842 (deleted)
lrwx------. 1 mysql mysql 64 1210 07:54 14 -> /var/lib/mysql/undo_002
lrwx------. 1 mysql mysql 64 1210 07:54 15 -> /var/lib/mysql/ibtmp1
lrwx------. 1 mysql mysql 64 1210 07:54 16 -> /var/lib/mysql/#innodb_temp/temp_1.ibt
lrwx------. 1 mysql mysql 64 1210 07:54 17 -> /var/lib/mysql/#innodb_temp/temp_2.ibt
lrwx------. 1 mysql mysql 64 1210 07:54 18 -> /var/lib/mysql/#innodb_temp/temp_3.ibt
lrwx------. 1 mysql mysql 64 1210 07:54 19 -> /var/lib/mysql/#innodb_temp/temp_4.ibt

 

posted @ 2020-03-14 12:02  Vincen_shen  阅读(401)  评论(0编辑  收藏  举报