linux lsof加-p和不加-p的区别(第一次用就被坑难受)

本文通过实例分析了Linux中使用lsof命令统计进程文件句柄数的情况,探讨了-p参数指定进程与不指定的区别。在解决系统资源占用问题时,发现一个进程的文件句柄数与其线程数有关,每个线程共享打开的文件,导致统计结果差异。通过统计线程数和每个线程的文件句柄重复次数,得出结论:进程的文件句柄数应考虑其线程共享资源的因素。
摘要由CSDN通过智能技术生成

针对以下两条命令,先给自己的结论吧:加-p是指定进程,不加-p的是线程

(脚本小白,没找着出处,是根据数据观察的,欢迎各位大佬指正)

 

最近,系统出了一次问题,导致所有页面都打不开,接口都访问失败,当然作为运维小白,显然是不咋会看Linux的一些资源占用情况的,然后看了提交记录没改啥影响全局的东西,就埋头去看错误日志了,额,,,显然错误日志也不少,还没在错误日志的信息里提取出主要原因,大佬就说:我看了一下,文件句柄数超过默认的1024了。你看看是不是这个原因,果然日志文件里:java.io.IOException:Too many open files。然后就自己检查哪些打开流没关的,问题解决。

很久之后,领导:最近系统很慢啊,你把Linux的一些资源占用情况定时入库吧。我嘴上:好的。内心:这是要写jio本吗?我不会吖?╥﹏╥...。然后就开始各种翻博客,cpu、内存啥啥的,查到了,嗯,用top很顺利,优秀的文章又多,终于,到了文件句柄了,基本上都是:

统计各进程打开句柄数(执行结果:第一列是数量,第二列是pid):

lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more

统计单个进程打开句柄数(执行结果:只有数量):

lsof -p pid |wc -l

执行:

[root@localhost ~]# lsof -p 11211 |wc -l
437
[root@localhost ~]# lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more
  90688 11211
  46368 11055
  ...

这,不对啊,指定pid统计结果437,不指定pid统计结果90688,就算它时刻在变化,复制粘贴前后时间相差一秒,也没这么大变化吧,我网上搜啊搜啊,也搜不出为啥,不会是文件句柄打开没关导致泄露吧,跟领导汇报完,领导:不可能,60%都是你危言耸听,你再查查看。网上我是搜不到了,然后就把详细信息打出来对比了:

[root@localhost ~]# lsof -p 11211
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF      NODE NAME
java    11211 root  cwd       DIR              253,0        64 101221120 /n....
java    11211 root  rtd       DIR              253,0       281        64 /
java    11211 root  txt       REG              253,0      7734 100879130 /usr/...
....
#脚本大意:输出包含11211的行(不是很会脚本,表头是我单独执行lsof复制过来的,尴尬)
[root@localhost ~]# lsof |grep 11211
COMMAND     PID   TID      USER   FD      TYPE    DEVICE     SIZE/OFF     NODE NAME
java      11211            root  231u     IPv6    128887212       0t0     TCP localhost...
java      11211            root  232u     IPv6    128887213       0t0     TCP localhost...
java      11211            root  233u     IPv6    128886515       0t0     TCP localhost...
java      11211            root  234r      REG    253,0   3866653  102282 /usr/java/....
java      11211            root  235r      REG    253,0   2245827  102282 /usr/java/....
java      11211            root  236u     unix    0xfff       0t0  128879 socket
java      11211            root  237u     unix    0xfff       0t0  128879 socket
java      11211 11212      root  cwd       DIR    253,0        64  101221 /n..
java      11211 11212      root  rtd       DIR    253,0       281      64 /
...

乍一看,这不一样的吗,再仔细看,咦,第二个多了一列,第三列的TID(线程ID),然后统计了一下TID的重复次数:

#脚本大致意思:只输出包含11211的行,读出每行的第三列,统计相同TID出现次数,排序
[root@localhost ~]# lsof |grep 11211 |awk '{print $3}'|sort|uniq -c |sort -nr|more
    436 root
    436 28785
    436 28784
    436 18749
    436 18748
    436 18747
    436 18746
    436 18741
    436 18740
    436 18699
    436 18698
    436 18697
    ...

欸,你发现没,每个线程重复次数都是一样的,这表明什么,不晓得,但是这么一致肯定是有问题的,再回想一下,当年葛大爷(教操作系统的最严厉的老师)的话:进程持有资源,线程基本不持有资源,共享进程所持有的资源。再翻了一下,找到一张图(有时候图会显示不出来,手动转成了表格):

一般情况下线程共享与独享资源的划分

线程共享

线程独享

地址空间程序计数器
全局变量寄存器
打开的文件
子进程状态字
闹钟 
信号及信号服务成勋 
记账信息 

其他的看不懂没关系,但是我看到了 打开的文件 属于 线程共享 ,再统计这个进程的线程数:

#统计11211进程的线程数
[root@localhost ~]# ps -T -p 11211 |wc -l
209

436*209不就约等于9万多,啊~~~~意思是每个打开文件算是线程共享,所以一个进程有多少个线程就重复了多少次?自我感觉大概就是这意思吧(小声逼逼:虽然也不晓得对不对,毕竟脚本小白,也没找着出处)

好了,根据以上我的结论是:

lsof -p 18088 |wc -l这个脚本统计的是指定进程的文件句柄打开数

lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more这个脚本我当然不敢说是错的,但不是我想要的,起码如果进程不是只有单个线程的话,不是统计的各进程打开句柄数

 

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值