再续《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. Jmeter(三十二)Jmeter Question 之 “自定义函数开发”

    “技术是业务的支撑”,已经不是第一次听到这句话,因为有各种各样的需求,因此衍生了许多各种各样的技术.共勉! 前面有提到提到过Jmeter的安装目录结构,也提到Jmeter的常用函数功能,有部分工作使用 ...

  2. 两种解决方法 PHP Warning: File upload error - unable to create a temporary file in Unknown

    原因:上传文件时,没有管理员权限的你不能读取临时文件夹; 解决方法(两种)找到临时文件夹并给当前访问用户所有权限; 方法一: 找到Apache默认的临时文件,步骤如下: 1.找到临时文件夹,一般在C: ...

  3. linux驱动开发—基于Device tree机制的驱动编写

    前言Device Tree是一种用来描述硬件的数据结构,类似板级描述语言,起源于OpenFirmware(OF).在目前广泛使用的Linux kernel 2.6.x版本中,对于不同平台.不同硬件,往 ...

  4. javasript-for循环

    先来个for循环的例子: var i=0,j=0; for(;i<10,j<6;i++,j++){ k=i+j; } console.log(k) 想知道会输出什么,首先得知道完整循环了多 ...

  5. Python利用脚本2.x到3自动转换

    本文介绍一下在windows 10 环境下如何使用这个工具: 1)首先要先安装好python3,可到官网下载https://www.python.org/ 2)使用Windows 命令提示符(cmd) ...

  6. Android--普通注册页面实现(无功能)

    reg.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmln ...

  7. java正则表达式替换空格和换行符

    public class StringUtil {        public static String getStringNoBlank(String str) {            if(s ...

  8. gulp安装,淘宝镜像

    命令:express -e ./ express表示安装express -e表示使用ejs作为模板 ./表示当前目录中 (使用上面的命令之前我们应该使用npm安装express框架 sudo npm ...

  9. angularjs数据交互

    异步问题ajax异步请求数据完数据后给$scope赋值的时候需要检查$scope的数据更新没有.要不然无法绑定数据. <!DOCTYPE html> <html ng-app=&qu ...

  10. 在Java中多段执行adb或者shell的命令

    public void Bale (String logname){ //ant打包 System.out.println("-----------正在执行ant编译-----------& ...