再续《linux 3.10 一次softlock排查》,看运行态进程数量之多:

crash> mach
MACHINE TYPE: x86_64
MEMORY SIZE: GB
CPUS:
HYPERVISOR: KVM
PROCESSOR SPEED: Mhz
HZ:
PAGE SIZE:
KERNEL VIRTUAL BASE: ffff880000000000
KERNEL VMALLOC BASE: ffffc90000000000
KERNEL VMEMMAP BASE: ffffea0000000000
KERNEL START MAP: ffffffff80000000
KERNEL MODULES BASE: ffffffffc0000000
KERNEL STACK SIZE:
IRQ STACK SIZE:
IRQ STACKS:
CPU : ffff880b52a00000
CPU : ffff880b52a40000
CPU : ffff880b52a80000
CPU : ffff880b52ac0000
CPU : ffff880b52b00000
CPU : ffff880b52b40000
CPU : ffff880b52b80000
CPU : ffff880b52bc0000
CPU : ffff880b52c00000
CPU : ffff880b52c40000
CPU : ffff880b52c80000
CPU : ffff880b52cc0000
CPU : ffff881692200000
CPU : ffff881692240000
CPU : ffff881692280000
CPU : ffff8816922c0000
CPU : ffff881692300000
CPU : ffff881692340000
CPU : ffff881692380000
CPU : ffff8816923c0000
CPU : ffff881692400000
CPU : ffff881692440000
CPU : ffff881692480000
CPU : ffff8816924c0000
DOUBLEFAULT STACK SIZE:

但是,我们来看,有多少个running进程呢?

ps |grep -i RU
> ffffffff81a09480 RU 0.0 [swapper/]
ffff88016e798fd0 RU 0.0 [swapper/]
ffff88016e799fa0 RU 0.0 [swapper/]
ffff88016e79af70 RU 0.0 [swapper/]
ffff88016e79bf40 RU 0.0 [swapper/]
ffff88016e79cf10 RU 0.0 [swapper/]
ffff88016e79dee0 RU 0.0 [swapper/]
ffff88016e79eeb0 RU 0.0 [swapper/]
> ffff88016e008000 RU 0.0 [swapper/]
ffff88016e008fd0 RU 0.0 [swapper/]
ffff88016e009fa0 RU 0.0 [swapper/]
> ffff88016e00af70 RU 0.0 [swapper/]
> ffff880beeaceeb0 RU 0.0 [swapper/]
ffff880beeacdee0 RU 0.0 [swapper/]
ffff880beeaccf10 RU 0.0 [swapper/]
> ffff880beeacbf40 RU 0.0 [swapper/]
ffff880beeacaf70 RU 0.0 [swapper/]
ffff880beeac9fa0 RU 0.0 [swapper/]
ffff880beeb10000 RU 0.0 [swapper/]
ffff880beeb10fd0 RU 0.0 [swapper/]
ffff880beeb11fa0 RU 0.0 [swapper/]
ffff880beeb12f70 RU 0.0 [swapper/]
ffff880beeb13f40 RU 0.0 [swapper/]
ffff880beeb14f10 RU 0.0 [swapper/]
ffff880beeac8000 RU 0.0 systemd
ffff88016e726eb0 RU 0.0 [rcu_sched]
ffff88016e00eeb0 RU 0.0 [watchdog/]
ffff88016e00cf10 RU 0.0 [ksoftirqd/]
ffff88016e040fd0 RU 0.0 [watchdog/]
ffff88016e045ee0 RU 0.0 [watchdog/]
ffff88016e098000 RU 0.0 [ksoftirqd/]
ffff88016e09af70 RU 0.0 [watchdog/]
ffff88016e111fa0 RU 0.0 [watchdog/]
ffff88016e163f40 RU 0.0 [watchdog/]
ffff88016e198fd0 RU 0.0 [watchdog/]
ffff880beeb3bf40 RU 0.0 [watchdog/]
ffff880beeb7dee0 RU 0.0 [watchdog/]
ffff880beebaaf70 RU 0.0 [watchdog/]
ffff880beebf0000 RU 0.0 [watchdog/]
ffff880beebf4f10 RU 0.0 [watchdog/]
ffff880bee021fa0 RU 0.0 [watchdog/]
ffff880bee026eb0 RU 0.0 [watchdog/]
ffff880bee050fd0 RU 0.0 [ksoftirqd/]
ffff880bee053f40 RU 0.0 [watchdog/]
ffff880bee078fd0 RU 0.0 [watchdog/]
ffff880b06e15ee0 RU 0.5 zte_uep1
ffff88077fe08000 RU 0.5 zte_uep1
ffff8814af3fbf40 RU 0.5 zte_uep1
ffff8807967d6eb0 RU 0.5 java
ffff880b4f5b5ee0 RU 0.0 systemd-journal
ffff8809a4aacf10 RU 0.5 zte_uep1
ffff880036a6cf10 RU 0.5 zte_uep1
ffff880036022f70 IN 0.0 [xfs_mru_cache]
。。。。。。。。。。。。。。。。。。。。列不完

看看个数:

crash> ps |grep -w RU |wc -l

经常敲top的人肯定知道,running的进程数,一般是小于等于cpu的核数的,那为啥这个机器上这么多的running呢?为了排除是crash工具的问题,在从runqueue的角度来看下:

crash> p runqueues
PER-CPU DATA TYPE:
struct rq runqueues;
PER-CPU ADDRESSES:
[0]: ffff880b52a17c00
[1]: ffff880b52a57c00
[2]: ffff880b52a97c00
[3]: ffff880b52ad7c00
[4]: ffff880b52b17c00
[5]: ffff880b52b57c00
[6]: ffff880b52b97c00
[7]: ffff880b52bd7c00
[8]: ffff880b52c17c00
[9]: ffff880b52c57c00
[10]: ffff880b52c97c00
[11]: ffff880b52cd7c00
[12]: ffff881692217c00
[13]: ffff881692257c00
[14]: ffff881692297c00
[15]: ffff8816922d7c00
[16]: ffff881692317c00
[17]: ffff881692357c00
[18]: ffff881692397c00
[19]: ffff8816923d7c00
[20]: ffff881692417c00
[21]: ffff881692457c00
[22]: ffff881692497c00
[23]: ffff8816924d7c00
crash> struct rq.nr_running ffff880b52a17c00
nr_running = 7
crash> struct rq.nr_running ffff880b52a57c00
nr_running = 152

挨个查看一下nr_running个数,然后脚本统计如下:

grep 'nr_running =' 1.txt |awk '{print $3}BEGIN{sum=0;num=0}{sum+=$3;num+=1}END{printf "%d\n",sum}'
7
152
113
138
65
4
4
38
4
148
43
1
1
141
4
43
107
102
91
110
108
105
98
3
1630-------------总数

为什么这个总数和我们ps看到的RU状态的总数不一致呢?一开始还以为是percpu统计的瞬时值问题,但是这两个总数的相差:1654-1630=24,刚好和cpu的核数一致。

ps |grep -w 'RU'|grep 'swapper'
> ffffffff81a09480 RU 0.0 [swapper/]
ffff88016e798fd0 RU 0.0 [swapper/]
ffff88016e799fa0 RU 0.0 [swapper/]
ffff88016e79af70 RU 0.0 [swapper/]
ffff88016e79bf40 RU 0.0 [swapper/]
ffff88016e79cf10 RU 0.0 [swapper/]
ffff88016e79dee0 RU 0.0 [swapper/]
ffff88016e79eeb0 RU 0.0 [swapper/]
> ffff88016e008000 RU 0.0 [swapper/]
ffff88016e008fd0 RU 0.0 [swapper/]
ffff88016e009fa0 RU 0.0 [swapper/]
> ffff88016e00af70 RU 0.0 [swapper/]
> ffff880beeaceeb0 RU 0.0 [swapper/]
ffff880beeacdee0 RU 0.0 [swapper/]
ffff880beeaccf10 RU 0.0 [swapper/]
> ffff880beeacbf40 RU 0.0 [swapper/]
ffff880beeacaf70 RU 0.0 [swapper/]
ffff880beeac9fa0 RU 0.0 [swapper/]
ffff880beeb10000 RU 0.0 [swapper/]
ffff880beeb10fd0 RU 0.0 [swapper/]
ffff880beeb11fa0 RU 0.0 [swapper/]
ffff880beeb12f70 RU 0.0 [swapper/]
ffff880beeb13f40 RU 0.0 [swapper/]
ffff880beeb14f10 RU 0.0 [swapper/]

原来是因为idle进程默认在running态,但是并不算到nr_running的计数中:

crash> ps |grep -w 'RU' |grep -w '12'
> 0 0 12 ffff880beeaceeb0 RU 0.0 0 0 [swapper/12]
12 2 1 ffff88016e00eeb0 RU 0.0 0 0 [watchdog/1]-----------这个不是12cpu的进程
22237 1 12 ffff881254b5eeb0 RU 1.0 14321692 912420 1_scheduler
crash> struct rq.nr_running ffff881692217c00
nr_running = 1

为啥running这么多呢?查看处于running状态的task,堆栈都是 __schedule ,也就是就绪队列很长,

来挑一些看看堆栈:

crash> bt
PID: TASK: ffff8809d42daf70 CPU: COMMAND: "java"
# [ffff88099eb93d58] __schedule at ffffffff816b6165
# [ffff88099eb93dc0] schedule at ffffffff816b6ae9
# [ffff88099eb93dd0] schedule_hrtimeout_range_clock at ffffffff816b5852
# [ffff88099eb93e68] schedule_hrtimeout_range at ffffffff816b5903
# [ffff88099eb93e78] ep_poll at ffffffff812526de
# [ffff88099eb93f30] sys_epoll_wait at ffffffff81253b9d
# [ffff88099eb93f80] system_call_fastpath at ffffffff816c2789
RIP: 00007ffa43a652c3 RSP: 00007ffa2595b818 RFLAGS:
RAX: 00000000000000e8 RBX: ffffffff816c2789 RCX: 00000000e14ef930
RDX: RSI: 00000000047a5000 RDI:
RBP: 00007ffa2595b630 R8: R9:
R10: R11: R12: 0000016547341bca
R13: R14: R15: 00000000047a5000
ORIG_RAX: 00000000000000e8 CS: SS: 002b
crash> bt
PID: TASK: ffff8809cbe03f40 CPU: COMMAND: "java"
# [ffff880a4eedbd58] __schedule at ffffffff816b6165
# [ffff880a4eedbdc0] schedule at ffffffff816b6ae9
# [ffff880a4eedbdd0] schedule_hrtimeout_range_clock at ffffffff816b5852
# [ffff880a4eedbe68] schedule_hrtimeout_range at ffffffff816b5903
# [ffff880a4eedbe78] ep_poll at ffffffff812526de
# [ffff880a4eedbf30] sys_epoll_wait at ffffffff81253b9d
# [ffff880a4eedbf80] system_call_fastpath at ffffffff816c2789
RIP: 00007f7bb9bb72c3 RSP: 00007f7b8f060510 RFLAGS:
RAX: 00000000000000e8 RBX: ffffffff816c2789 RCX: 00000000ffffffff
RDX: RSI: 0000000005be3000 RDI:
RBP: 00007f7b8f060310 R8: R9:
R10: 00000000000003e8 R11: R12:
R13: R14: 00000000000003e8 R15: 0000000005be3000
ORIG_RAX: 00000000000000e8 CS: SS: 002b
crash> task_struct.state ffff8809cbe03f40
state =

看看状态值的宏:

#define TASK_RUNNING        0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8

再看看占有cpu的进程的堆栈,发现基本都在等锁,原本大家很快都能执行完,然后放到等待队列里面去,但是由于前面某个进程执行占着cpu不放,那么因为等待资源而得到唤醒的,处于就绪队列里面的进程自然得不到调度。当然这个是非抢占式内核的特点,高优先级的进程,也得等低优先级的进程主动放弃cpu,哪怕你已经在就绪队列,哪怕你的状态已经被改成了running,但就得等着。

linux 再多的running也挡不住锁的更多相关文章

  1. linux网络编程之posix信号量与互斥锁

    继上次学习了posix线程之后,这次来讨论一下posix信号量与互斥锁相关的知识: 跟posix消息队列,共享内存的打开,关闭,删除操作一样,不过,上面的函数是对有名信号量进行操作,通过man帮助可以 ...

  2. Linux再学习(一)-学习路线规划

    1 抛弃旧文化,迎接Linux命令新文化 Linux第一步,从Windows思维,切换到Linux的"命令行+文件"模式 在Linux中,做什么都有相应命令.一般就在bin或者sb ...

  3. Linux再谈互斥锁与条件变量

    原文地址:http://blog.chinaunix.net/uid-27164517-id-3282242.html pthread_cond_wait总和一个互斥锁结合使用.在调用pthread_ ...

  4. 挡不住的好奇心:ASP.NET 5是如何通过XRE实现跨平台的

    .NET程序员也有自己的幸福,.NET的跨平台是一种幸福,.NET的开源也是一种幸福,而更幸福的是可以通过开源的.NET了解.NET是如何一步步走向跨平台的,所以幸福是一种过程. 在.NET跨平台的进 ...

  5. java中的finally用return也挡不住

    今晚做了科达的题,有一题就是这个意思,我自以为return中断一切,然而事实摆在眼前:

  6. 本科毕业平均年薪 30 万!经济寒冬挡不住 AI 人才的火热!

    互联网行业遭遇寒冬,企业纷纷裁员缩招,而 BAT 和硅谷明星公司对 AI 人才的投入却并不见放缓.为争夺相关人才,给应届毕业生开出的平均年薪高达 30 万. 而 TensorFlow 作为当下最流行的 ...

  7. Linux 线程同步的三种方法(互斥锁、条件变量、信号量)

    互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...

  8. Linux组件封装(一)中互斥锁MutexLock的封装

    本文对Linux中的pthread_mutex_t做一个简易的封装. 互斥锁主要用于互斥,互斥是一种竞争关系,主要是某一个系统资源或一段代码,一次做多被一个线程访问. 条件变量主要用于同步,用于协调线 ...

  9. 求你了,别再问我Zookeeper如何实现分布式锁了!!!

    导读 真是有人(锁)的地方就有江湖(事务),今天不谈江湖,来撩撩人. 分布式锁的概念.为什么使用分布式锁,想必大家已经很清楚了.前段时间作者写过Redis是如何实现分布式锁,今天这篇文章来谈谈Zook ...

随机推荐

  1. [UE4]位移和形变 Render Transform

      任何UI控件都有Render Transform属性. 一.Transform,对应游戏场景中的Transform 1.Translation:位置,平移.对应游戏场景的Transform中的Lo ...

  2. Java基础知识_毕向东_Java基础视频教程笔记(5-10 面向对象)

    06天-05-面向对象(帮助文档的制作javadoc):java文档生成命令:javadoc -d filepatn demo.java   -author -version(可选)一个类中默认会有一 ...

  3. mac一些设置

    Mac自带了的JDK6,安装在目录:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/下. JDK8则需要自己到Oracle官网下载安装对应的版本. ...

  4. C# Microsoft.Office不存在空间名称Interop和Excel

    在实际开发过程中,我们经常会对Excel表进行操作.相信大家都都已经很熟悉C#操作Excel的步骤:添加引用->COM->Microsoft Office Excel 11 Object. ...

  5. 新的开始 接触ASP.NET Core跨平台的框架

    今天我刚学习了使用Visual Studio 2015新建了.NET Core项目写了一个小的CSHTML代码.按我的话说就是,把C#和HTML合起来使用了,写了一个简单的关于学生的“增” “删” “ ...

  6. Docker使用札记 - 使用中遇到的问题总结

    1. 启动容器时报错误“: No such file or directory” 一般来说作为容器应用的入口都是entrypoint.sh文件,也就是Dockerfile最后一条指令为是: ENTRY ...

  7. css自定义鼠标

    亲们支持我的新博客哦==>地址(以后更新会尽量在新博客更新,欢迎大家访问加入我的后宫w) ) css自定义鼠标 效果展示==> 注意: 1.支持jpg/png/ico格式的展示鼠标格式,为 ...

  8. 关于CSS3属性transition的触发

    关于怎么触发transition的效果,前面有篇文章说过一次,<关于transition和animation>,而且在实际的项目生产中,也是一直这么使用的,因为明明知道直接添加class是 ...

  9. [oracle,2017-11-28] 怎么判断oracle数据库中字段是否为空

    要给oracle某个字段插入空值非常简单 insert into table(column) values('') 但是查询的时候通过语句 select * from table where colu ...

  10. django之视图系统 views.py-->主要内容(FBV和CBV、dispath、request对象和request.FILES、JsonResponse)

    一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 一 视图的实现可以基于两种方法: 1 基于函数的形式 FBV 使用装饰器装饰FBV  直接在上 ...