FD文件描述符

一:文件描述符概念
  元数据(记录文件的大小,拥有者,所属组,大小,修改日期等)到文件的映射。当应用程序打开某个文件时,内核就会返回唯一的文件描述符给应用程序,应用程序通过文件描述符来引用文件。
   linux系统对每个用户,进程,整个系统能打开的文件描述符是有限制的,默认值是1024.当我们在系统或应用日志中碰到“too many open file”时,并不是整个系统打开太多的文件,而是某个用户,进程或系统打开的文件描述符已经达到限制。这个时候可以增加文件描述符的数量限制来解决这个问题。
二:常用关于文件描述符的相关命令lsof
   2.1 安装lsof
在Centos6中没有lsof命令,这时可以通过yum install lsof命令来安装lsof工具
   2.2 获取 系统打开的文件描述符数量 cat /proc/sys/fs/file-nr
   cat /proc/sys/fs/file-nr
    2080 0 387517
   //第一列 2080 :已分配的FD数量
   //第二列 0    :已分配未使用的FD数量
   //第三列 387517:系统可用的最大的FD数量

备注:/proc目录是运行时访问内核数据结构,改变内核内置的机制,为访问系统内核提供接口。存储在 内存当中。
    2.3 获取进程打开的文件描述符数量 以vi程序为例
     2.3.1 pidof vi
      12874
      //第一列 12874 vi程序的进程号
     2.3.2 ls -l /proc/12874/fd
      total 0
    lrwx------ 1 root root 64 Jun  2 14:28 0 -> /dev/pts/1
    lrwx------ 1 root root 64 Jun  2 14:28 1 -> /dev/pts/1
    lrwx------ 1 root root 64 Jun  2 14:00 2 -> /dev/pts/1
    lrwx------ 1 root root 64 Jun  2 14:28 4 -> /tmp/.2.txt.swp
     //显示vi程序用了4个文件描述符FD
  备注:pidof找出正在运行程序的进程号
     2.4 更改文件描述符限制
  当在系统或应用日志中碰到"too many open files"时,需要增加文件描述符的数量限制来解决此问题。在实际应用中,系统的默认文件描述符比较大,所以一般只需要更改用户和进程的文件描述符FD两者的限制数量
     2.4.1首先查看shell启动进程时,各个限制资源 ulimit -a 或ulimit -n
     [root@bdi23 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 30516
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 30516
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

     备注:  ulimit -a用于显示shell资源的限制,图中红色的为文件描述符的限制数量

   [root@bdi23 ~]# ulimit -n
   1024
     备注:ulimit -n 用于显示用户或进程的FD文件描述符限制
    2.4.2更改FD文件描述符限制
       2.4.2.1临时更改FD文件描述符限制
     也就是说只在当前会话中更改FD文件描述符限制,退出重新登录后,系统会还原默认的1024 FD文件描述符限制.当前用户当前会话有效
     [root@bdi23 ~]# ulimit -n 2000
     备注:用此命令可以设置当前会话原FD数量限制
      再用ulimit -n或ulimit -a可以查看设置是否成功
     [root@bdi23 ~]# ulimit -n
     2000
     [root@bdi23 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 30516
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 2000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 30516
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

       2.4.2为某个用户永久生效FD限制数量
    当退出后重新登录,此用户的FD限制数量为修改后的限制数量
    [root@bdi23 ~]# vi /etc/security/limits.conf
    在文件末尾加入
    fly              hard    nofile          100
   //第一列 fly :指定的用户名,更改后fly用户的每一个进程都可以使用的FD限制数量为100
   //第二列 hard:限制类型,soft,当系统达到此类型的FD限制数量时,会在/var/log/messages中记录一条日志,但不影响使用。hard,当系统达到此类型的FD限制数量时,也会记录一条日志,但会影响使用
   //第三列 nofile:限制的内容
   //第四列 限制的值

     2.4.3 用fly用户登录系统,ulimit -n 或 ulimit -a 查看设置结果
    [fly@bdi23 ~]$ ulimit -n
     100
[fly@bdi23 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 30516
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 100
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

备注:还可以通过修改某个用户的.bash_profile文件来达到这个效果,在文件中加入ulimit -n 200
   [root@bdi23 ~]# echo "ulimit -n 200" >> /home/fly/.bash_profile

这个在机器上试的时候,没有成功。没有成功的原因是因为在/etc/security/limits.conf文件中添加了fly hard nofile 100.所以由此可见,/etc/security/limits.conf的文件优先级要高于.bash_profile文件。
       2.4.4为整个系统设置最大FD数量
     echo "51200" >> /proc/sys/fs/file-max
     root@bdi23 ~]# cat /proc/sys/fs/file-nr
     2304  0 51200
  备注:像这样设置后,系统重启会将最大值默认还原
       2.4.5为整个系统永久设置最大值
      echo "fs.file-max = 51200" >> /etc/systcl.conf
   3 lsof的常用命令
       3.1查看整个系统的文件打开数量
        [root@bdi23 ~]# lsof | wc -l
         3491
       3.2查看某个用户打开的文件数量
         [root@bdi23 ~]# lsof -u k | wc -l
         102
       3.3查看某个程序打开的文件数量
         [root@bdi23 ~]# pidof vim
          9777
          [root@bdi23 ~]# lsof -p 9777 | wc -l
           27
  


最常见的文件交互方式是系统调用。
一文件表:在对文件进行读写操作之前要对文件进行打开操作,内核会为每个进程维护一张打开的文件表。子进程会维护你进程的文件表副本,当子进程关闭文件时不会影响父进程的文件表,只会影响自己的文件表。这个文件表里面存储的是FD[每个进程至少包含三个FD]
二打开文件
  最常见的文件访问方法是系统调用read(),write().但之前要通过open()或create()来打开文件。读写完成还要close()文件。

  





      
 

猜你喜欢

转载自wangqinghan.iteye.com/blog/2306290