• 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
  • 相关阅读:
    SQL优化索引
    如何减轻工作压力(一)
    奥巴马对美国影响最大的十句话
    10种职场潜规则
    Linux中的7件武器详解
    linux时间同步,ntpd、ntpdate
    Style中Position属性详解
    vsftp配置大全超完整版
    Linux 技巧:使用 screen 管理你的远程会话
    MySQL下mysql.sock丢失问题的解决
  • 原文地址:https://www.cnblogs.com/vincenshen/p/12491400.html
Copyright © 2020-2023  润新知