文件描述符

2018-11-28  本文已影响0人  tracy_668

文件描述符简介

在linux系统中,一切皆文件,当进程打开现有文件或者创建新文件时,内核向进程返回一个文件描述符,文件描述符在形式上是一个非负整数,实际上它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。所有执行io操作的系统调用都会通过文件描述符执行。

文件描述符和进程的关系

系统为了维护文件描述符,建立了三个表:


image.png image.png

如上图所示:

命令示例

一个常见命令:

我们在linux下经常会碰到: nohup command>/dev/null 2>&1 & 这样形式的命令,我们把这条命令分解下:

command>a 2>a 与 command>a 2>&1的区别

通过上面的分析,command>a 2>&1等价于command 1>a 2>&1可以理解为执行command产生的标准输出重定向到文件a中,标准错误也重定向到文件a中,那么是否就说 command 1>a 2>&1等价于command 1>a 2>a呢,command 1>1 2>&1 与command 1>a 2>a还是有区别的,前者只打开一次文件a, 后者会打开文件两次,并导致stdout被stderr覆盖。**&1的含义可以理解为标准输出的引用, 引用的就是重定向标准输出产生打开的a。

例子说明
/test.sh
#!/bin/sh
t
date

chmod +x test.sh为test.sh增加执行权限。这里我们弄了两条命令,其中t指令并不存在,执行会报错,会输出到stderr。date能正常执行,执行会输出当前时间,会输出到stdout。
我们发现stderr并没有被重定向到res1.log中,stderr被打印到了屏幕上。这也进一步证明了上面说的./test.sh > res1.log等价于./test.sh 1>res1.log

执行./test.sh>res2.log 2>&1结果为

这次我们发现stdout和stderr都被重定向到了res2.log中了。上面我们未对stderr也就是2说明如何输出,stderr就输出到了屏 幕上,这里我们不仅对stdout进行说明,重定向到res2.log中,对标准错误也进行了说明,让其重定向到res2.log的引用即 res2.log的文件描述符中。

@ubuntu:~$ bash test.sh 1>test.log 2>&1
@ubuntu:~$ cat test.log                
test.sh: line 2: t: command not found
Tue Nov 27 15:56:02 PST 2018
@ubuntu:~$ bash test.sh 1>test.log 2>test.log
@ubuntu:~$ cat test.log                      
Tue Nov 27 15:56:47 PST 2018
ot found // 被覆盖了

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
$ command > file 2>&1

或者

$ command >> file 2>&1

查看该进程的限制
 ps -ef | grep redis 
cat /proc/16943/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             3731                 3731                 processes 
Max open files            10032                10032                files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       3731                 3731                 signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us  

在 Max open files 那一行,可以看到当前设置中最大文件描述符的数量为10032

  1. soft 指的是当前系统生效的设置值
  2. hard 指的是系统中所能设定的最大值
查看该进程占用了多少个文件描述符
 ll /proc/16943/fd/ 
total 0
dr-x------ 2 wusong wusong  0 Nov 27 07:42 ./
dr-xr-xr-x 9 wusong wusong  0 Nov 27 07:42 ../
lrwx------ 1 wusong wusong 64 Nov 27 07:46 0 -> /dev/pts/8
lrwx------ 1 wusong wusong 64 Nov 27 07:46 1 -> /dev/pts/8
lrwx------ 1 wusong wusong 64 Nov 27 07:42 2 -> /dev/pts/8
lrwx------ 1 wusong wusong 64 Nov 27 07:46 3 -> anon_inode:[eventpoll]
lrwx------ 1 wusong wusong 64 Nov 27 07:46 4 -> socket:[329365]
lrwx------ 1 wusong wusong 64 Nov 27 07:46 5 -> socket:[329366]

实际应用过程中,如果出现“Too many open files” , 可以通过增大进程可用的文件描述符数量来解决,但往往故事不会这样结束,很多时候,并不是因为进程可用的文件描述符过少,而是因为程序bug,打开了大量的文件连接(web连接也会占用文件描述符)而没有释放。程序申请的资源在用完后及时释放,才是解决“Too many open files”的根本之道。

上一篇 下一篇

猜你喜欢

热点阅读