Browse Source

:pencil2: update

nick 6 years ago
parent
commit
b0367180db
5 changed files with 45 additions and 373 deletions
  1. 15 15
      cpu-context.md
  2. 15 15
      cpu-used.md
  3. 1 328
      package-lock.json
  4. 3 3
      stress-sysstat-mpstat-pidstat-watch-uptime.md
  5. 11 12
      zombie-process.md

+ 15 - 15
cpu-context.md

@@ -1,6 +1,6 @@
 ## 什么是 CPU 上下文
 
-Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。而在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)
+Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。而在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)
 
 CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任务前,必须的依赖环境,因此也被叫做 CPU 上下文。
 
@@ -10,7 +10,7 @@ CPU 上下文切换,是保证 Linux 系统正常工作的核心功能之一,
 
 ## CPU 上下文切换分类
 
-CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置, 运行新任务。
+CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。
 
 根据任务的不同,CPU 的上下文切换就可以分为 __进程上下文切换__、 __线程上下文切换__ 以及 __中断上下文切换__
 
@@ -18,8 +18,8 @@ CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU
 
 Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间,CPU 特权等级的 Ring 0 和 Ring 3。
 
-内核空间(Ring 0)具有最高权限,可以直接访问所有资源;
-用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统 调用陷入到内核中,才能访问这些特权资源。
+内核空间(Ring 0))具有最高权限,可以直接访问所有资源;
+用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统 调用陷入到内核中,才能访问这些特权资源。
 
 进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。
 
@@ -29,18 +29,18 @@ Linux 按照特权等级,把进程的运行空间分为内核空间和用户
 
 CPU 寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核态代码,CPU 寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。
 
-而系统调用结束后,CPU 寄存器需要 __恢复__原来保存的用户态,然后再切换到用户空间,继续运行进程。所以, __一次系统调用的过程,其实是发生了两次 CPU 上下文切换__。
+而系统调用结束后,CPU 寄存器需要__恢复__原来保存的用户态,然后再切换到用户空间,继续运行进程。所以, __一次系统调用的过程,其实是发生了两次 CPU 上下文切换__。
 
 需要注意的是,系统调用过程中,并不会涉及到虚拟内存等进程用户态的资源,也
 不会切换进程。这跟我们通常所说的进程上下文切换是不一样的: __进程上下文切换,是指从一个进程切换到另一个进程运行。而系统调用过程中一直是同一个进程在运行__ 。所以,__系统调用过程通常称为特权模式切换,而不是上下文切换__。但实际上,系统调用过程中,CPU 的上下文切换还是无法避免的。
 
 #### 进程在什么时候才会被调度到 CPU 上运行
 
-最容易想到的一个时机,就是进程执行完终止了,它之前使用的 CPU 会释放出来,这个时候再从就绪队列里,拿一个新的进程过来运行。其实还有很多其他场景,也会触发进程调度
+最容易想到的一个时机,就是进程执行完终止了,它之前使用的 CPU 会释放出来,这个时候再从就绪队列里,拿一个新的进程过来运行。其实还有很多其他场景,也会触发进程调度
 
 其一,为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其它正在等待 CPU 的进程运行。
 
-其二,进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时
+其二,进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时
 候进程也会被挂起,并由系统调度其他进程运行。
 
 其三,当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度。
@@ -59,7 +59,7 @@ __线程与进程最大的区别在于,线程是调度的基本单位,而进
 
 所以,对于线程和进程,我们可以这么理解:__当进程只有一个线程时,可以认为进程就等于线程__。当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源。这些资源在上下文切换时是不需要修改的。另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文换时也是需要保存的。
 
-线程的上下文切换其实就可以分为两种情况:
+线程的上下文切换其实就可以分为两种情况
 
 第一种, 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样。
 
@@ -80,7 +80,7 @@ __线程与进程最大的区别在于,线程是调度的基本单位,而进
 
 vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分 析 CPU 上下文切换和中断的次数。
 
-下面就是一个 vmstat 的使用示例:
+下面就是一个 vmstat 的使用示例
 
 ```
 vmstat 5 #每隔 5 秒输出 1 组数据
@@ -94,19 +94,19 @@ procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 
 结果含义说明
 
-- cs(context switch)是每秒上下文切换的次数。
+- cs(context switch)是每秒上下文切换的次数。
 
-- in(interrupt)则是每秒中断的次数。
+- in(interrupt)则是每秒中断的次数。
 
-- r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
+- r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
 
-- b(Blocked)则是处于不可中断睡眠状态的进程数。
+- b(Blocked)则是处于不可中断睡眠状态的进程数。
 
 可以看到,这个例子中的上下文切换次数 cs 是 8 次,而系统中断次数 in 则是 2 次,而 就绪队列长度 r 和不可中断状态进程数 b 都是 0。
 
 vmstat 只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,就需要使用我们前面提到过的 pidstat 了。给它加上 -w 选项,你就可以查看每个进程上下文切换的情况了。
 
-示例:
+示例
 
 ```
 pidstat -w 5 # 每隔 5 秒输出 1 组数据
@@ -123,7 +123,7 @@ Linux 4.4.0-142-generic (10-53-166-171) 	07/07/2019 	_x86_64_	(2 CPU)
 04:05:58 PM     0        10      0.20      0.00  watchdog/0
 ```
 
-这个结果中有两列内容是我们的重点关注对象。一个是 cswch ,表示每秒自愿上下文切换 (voluntary context switches)的次数,另一个则是 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。
+这个结果中有两列内容是我们的重点关注对象。一个是 cswch ,表示每秒自愿上下文切换 (voluntary context switches)的次数,另一个则是 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。
 
 这两个概念一定要牢牢记住,因为它们意味着不同的性能问题:
 

+ 15 - 15
cpu-used.md

@@ -4,9 +4,9 @@ CPU 使用率是单位时间内 CPU 使用情况的统计,以百分比的方
 
 ## 怎么查看 CPU 使用率
 
-top 和 ps 是最常用的性能分析工具:top 显示了系统总体的 CPU 和内存使用情况,以及各个进程的资源使用情况。ps 则只显示了每个进程的资源使用情况。
+top 和 ps 是最常用的性能分析工具top 显示了系统总体的 CPU 和内存使用情况,以及各个进程的资源使用情况。ps 则只显示了每个进程的资源使用情况。
 
-top 默认每 3 秒刷新一次,输出格式为:
+top 默认每 3 秒刷新一次,输出格式为
 
 ```
 top - 21:12:50 up 21 days, 23:13,  2 users,  load average: 0.05, 0.04, 0.01
@@ -36,17 +36,17 @@ KiB Swap:        0 total,        0 free,        0 used.  3576656 avail Mem
 top 并没有细分进程的用户态 CPU 和内核态 CPU,需要查看每个进程的详细情况,可以用 pidstat ,它正是一个专门分析每个进程 CPU 使用情况的工具。
 
 
-下面的 pidstat 命令,就间隔 1 秒展示了进程的 5 组 CPU 使用率,包括:
+下面的 pidstat 命令,就间隔 1 秒展示了进程的 5 组 CPU 使用率,包括
 
-- 用户态 CPU 使用率 (%usr)
+- 用户态 CPU 使用率(%usr)
 
-- 内核态 CPU 使用率(%system)
+- 内核态 CPU 使用率(%system)
 
-- 运行虚拟机 CPU 使用率(%guest)
+- 运行虚拟机 CPU 使用率(%guest)
 
-- 等待 CPU 使用率(%wait)
+- 等待 CPU 使用率(%wait)
 
-- 以及总的 CPU 使用率(%CPU)
+- 以及总的 CPU 使用率(%CPU)
 
 最后的 Average 部分,还计算了 5 组数据的平均值。
 
@@ -78,13 +78,13 @@ Average:      113      4606    0.20    0.20    0.00    0.40     -  beam.smp
 
 ## CPU 使用率过高怎么办
 
-通过 top、ps、pidstat 等工具,你能够轻松找到 CPU 使用率较高(比如 100% )的进程,如果需要排查占用 CPU 的到底是代码里的哪个函数,推荐使用 perf。perf 是 Linux 2.6.31 以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
+通过 top、ps、pidstat 等工具,你能够轻松找到 CPU 使用率较高(比如 100% )的进程,如果需要排查占用 CPU 的到底是代码里的哪个函数,推荐使用 perf。perf 是 Linux 2.6.31 以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
 
 perf 分析 CPU 性能问题,两种最常见用法
 
 __第一种__
 
-perf top,类似于 top,它能够实时显示占用 CPU 时钟最多的函数或 者指令,因此可以用来查找热点函数,使用界面如下所示:
+perf top,类似于 top,它能够实时显示占用 CPU 时钟最多的函数或 者指令,因此可以用来查找热点函数,使用界面如下所示
 
 ```
 sudo perf top
@@ -110,15 +110,15 @@ Overhead  Shared Object            Symbol
    1.46%  perf                     [.] 0x000000000008e326
 ```
 
-输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和事件总数量(Event count)。比如这个例子中,perf 总共采集了 674 个 CPU 时间事件,而总事件数则为 149937500
+输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和事件总数量(Event count)。比如这个例子中,perf 总共采集了 674 个 CPU 时间事件,而总事件数则为 149937500
 
-另外,采样数需要我们特别注意。如果采样数过少(比如只有十几个),那下面的排序和 百分比就没什么实际参考价值了。
+另外,采样数需要我们特别注意。如果采样数过少(比如只有十几个),那下面的排序和 百分比就没什么实际参考价值了。
 
-再往下看是一个表格式样的数据,每一行包含四列,分别是:
+再往下看是一个表格式样的数据,每一行包含四列,分别是
 
 - 第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
 
-- 第二列 Shared     ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
+- 第二列 Shared     ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
 
 - 第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
 
@@ -126,7 +126,7 @@ Overhead  Shared Object            Symbol
 
 __第二种__
 
-就是 perf record 和 perf report。 perf top 虽然实时展示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续的分析。 而 perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。
+就是 perf record 和 perf report。perf top 虽然实时展示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续的分析。而 perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。
 
 ```
 sudo perf record -a #按 Ctrl+C 终止采样

+ 1 - 328
package-lock.json

@@ -1,330 +1,3 @@
 {
-  "requires": true,
-  "lockfileVersion": 1,
-  "dependencies": {
-    "boolbase": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
-    },
-    "cheerio": {
-      "version": "0.22.0",
-      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
-      "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=",
-      "requires": {
-        "css-select": "~1.2.0",
-        "dom-serializer": "~0.1.0",
-        "entities": "~1.1.1",
-        "htmlparser2": "^3.9.1",
-        "lodash.assignin": "^4.0.9",
-        "lodash.bind": "^4.1.4",
-        "lodash.defaults": "^4.0.1",
-        "lodash.filter": "^4.4.0",
-        "lodash.flatten": "^4.2.0",
-        "lodash.foreach": "^4.3.0",
-        "lodash.map": "^4.4.0",
-        "lodash.merge": "^4.4.0",
-        "lodash.pick": "^4.2.1",
-        "lodash.reduce": "^4.4.0",
-        "lodash.reject": "^4.4.0",
-        "lodash.some": "^4.4.0"
-      }
-    },
-    "css-select": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
-      "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
-      "requires": {
-        "boolbase": "~1.0.0",
-        "css-what": "2.1",
-        "domutils": "1.5.1",
-        "nth-check": "~1.0.1"
-      }
-    },
-    "css-what": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npm.taobao.org/css-what/download/css-what-2.1.3.tgz",
-      "integrity": "sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI="
-    },
-    "dom-serializer": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.1.1.tgz",
-      "integrity": "sha1-HsQFnihLq+027sKUHUqXChic58A=",
-      "requires": {
-        "domelementtype": "^1.3.0",
-        "entities": "^1.1.1"
-      }
-    },
-    "domelementtype": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz",
-      "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8="
-    },
-    "domhandler": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
-      "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=",
-      "requires": {
-        "domelementtype": "1"
-      }
-    },
-    "domutils": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
-      "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
-      "requires": {
-        "dom-serializer": "0",
-        "domelementtype": "1"
-      }
-    },
-    "entities": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz",
-      "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY="
-    },
-    "gitbook-plugin-3-ba": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-3-ba/-/gitbook-plugin-3-ba-0.9.0.tgz",
-      "integrity": "sha1-uR3Q7fCHYSeC/hdzkXfuJDSj1X4="
-    },
-    "gitbook-plugin-anchors": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-anchors/-/gitbook-plugin-anchors-0.7.1.tgz",
-      "integrity": "sha1-j1hbmasaYC6nFDQiWMlXI4427II=",
-      "requires": {
-        "cheerio": "*",
-        "github-slugid": "1.0.1"
-      }
-    },
-    "gitbook-plugin-back-to-top-button": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npm.taobao.org/gitbook-plugin-back-to-top-button/download/gitbook-plugin-back-to-top-button-0.1.4.tgz",
-      "integrity": "sha1-5iGDOLDvGdWOb2YAmUNQt26ANd8="
-    },
-    "gitbook-plugin-copy-code-button": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npm.taobao.org/gitbook-plugin-copy-code-button/download/gitbook-plugin-copy-code-button-0.0.2.tgz",
-      "integrity": "sha1-Q0UzIAtc9ZbChMFOHYu1d3IIRHU="
-    },
-    "gitbook-plugin-disqus": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-disqus/-/gitbook-plugin-disqus-0.1.0.tgz",
-      "integrity": "sha1-9gNfnEmHz1/JGA4FpkQ1pngpatY="
-    },
-    "gitbook-plugin-donate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-donate/-/gitbook-plugin-donate-1.0.2.tgz",
-      "integrity": "sha1-telSLNaTFY4a/ueAtfATk/0yP2Q="
-    },
-    "gitbook-plugin-edit-link": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-edit-link/-/gitbook-plugin-edit-link-2.0.2.tgz",
-      "integrity": "sha1-2PzZJ+ztgeemYqctWdtgnq/X5y8="
-    },
-    "gitbook-plugin-favicon": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-favicon/-/gitbook-plugin-favicon-0.0.2.tgz",
-      "integrity": "sha1-s+QWQvFSr8bEU1/ZtjXf4xtMh3I="
-    },
-    "gitbook-plugin-github": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-github/-/gitbook-plugin-github-2.0.0.tgz",
-      "integrity": "sha1-UWbnY8/MQC1DKIC3pshcHFS1ao0="
-    },
-    "gitbook-plugin-page-footer-ex": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npm.taobao.org/gitbook-plugin-page-footer-ex/download/gitbook-plugin-page-footer-ex-0.1.2.tgz",
-      "integrity": "sha1-AgbTvTuDSTyVIUR3ynajak5CyhM=",
-      "requires": {
-        "moment": "^2.10.6"
-      }
-    },
-    "gitbook-plugin-search": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-search/-/gitbook-plugin-search-2.2.1.tgz",
-      "integrity": "sha1-bSW1p3aZD6mP39+jfeMx944PaxM="
-    },
-    "gitbook-plugin-search-pro": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-search-pro/-/gitbook-plugin-search-pro-2.0.2.tgz",
-      "integrity": "sha1-fOduj2XCBESJucaSc2sj+B/mofI=",
-      "requires": {
-        "html-entities": "1.2.0"
-      }
-    },
-    "gitbook-plugin-sharing-plus": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-sharing-plus/-/gitbook-plugin-sharing-plus-0.0.2.tgz",
-      "integrity": "sha1-FstYGACikvAbvY19Ic6jID0Jcz8=",
-      "requires": {
-        "lodash": "^3.10.1"
-      }
-    },
-    "gitbook-plugin-sitemap": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-sitemap/-/gitbook-plugin-sitemap-1.2.0.tgz",
-      "integrity": "sha1-hneZN1C5ZYOMkG/nz8CiB8DQbcs=",
-      "requires": {
-        "sitemap": "1.5.0"
-      }
-    },
-    "gitbook-plugin-splitter": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/gitbook-plugin-splitter/-/gitbook-plugin-splitter-0.0.8.tgz",
-      "integrity": "sha1-8rBRMGD8kma0awQYLk7KHUtx+vw="
-    },
-    "github-slugid": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/github-slugid/-/github-slugid-1.0.1.tgz",
-      "integrity": "sha1-vM3QgVv61p2KNZ+k/WWUfWBuw8A="
-    },
-    "html-entities": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.0.tgz",
-      "integrity": "sha1-QZSMr4XOgv7Tbk5qDtNxpmZDeeI="
-    },
-    "htmlparser2": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz",
-      "integrity": "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=",
-      "requires": {
-        "domelementtype": "^1.3.1",
-        "domhandler": "^2.3.0",
-        "domutils": "^1.5.1",
-        "entities": "^1.1.1",
-        "inherits": "^2.0.1",
-        "readable-stream": "^3.1.1"
-      }
-    },
-    "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-    },
-    "lodash": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-      "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
-    },
-    "lodash.assignin": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
-      "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI="
-    },
-    "lodash.bind": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz",
-      "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU="
-    },
-    "lodash.defaults": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-      "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
-    },
-    "lodash.filter": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
-      "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4="
-    },
-    "lodash.flatten": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
-      "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
-    },
-    "lodash.foreach": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
-      "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
-    },
-    "lodash.map": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
-      "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM="
-    },
-    "lodash.merge": {
-      "version": "4.6.1",
-      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
-      "integrity": "sha1-rcJdnLmbk5HFliTzefu6YNcRHVQ="
-    },
-    "lodash.pick": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
-      "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM="
-    },
-    "lodash.reduce": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
-      "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs="
-    },
-    "lodash.reject": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz",
-      "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU="
-    },
-    "lodash.some": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
-      "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0="
-    },
-    "moment": {
-      "version": "2.24.0",
-      "resolved": "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz",
-      "integrity": "sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s="
-    },
-    "nth-check": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/nth-check/download/nth-check-1.0.2.tgz",
-      "integrity": "sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw=",
-      "requires": {
-        "boolbase": "~1.0.0"
-      }
-    },
-    "readable-stream": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.3.0.tgz",
-      "integrity": "sha1-y4ARqtAC63F78EApH+uoVpyYb7k=",
-      "requires": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      }
-    },
-    "safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
-    },
-    "sitemap": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-1.5.0.tgz",
-      "integrity": "sha1-RbPoib96XbDvvyxMb8sVbKh+EgE=",
-      "requires": {
-        "underscore": "^1.7.0",
-        "url-join": "^0.0.1"
-      }
-    },
-    "string_decoder": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.2.0.tgz",
-      "integrity": "sha1-/obnOLGVRK/nBGkkOyoe6SQOro0=",
-      "requires": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "underscore": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.9.1.tgz",
-      "integrity": "sha1-BtzjSg5op7q8KbNluOdLiSUgOWE="
-    },
-    "url-join": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz",
-      "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g="
-    },
-    "util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
-    }
-  }
+  "lockfileVersion": 1
 }

+ 3 - 3
stress-sysstat-mpstat-pidstat-watch-uptime.md

@@ -1,10 +1,10 @@
 ## 什么平均负载
 
-简单来说,平均负载是指单位时间内,系统处于 __可运行状态__  __不可中断状态__ 的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
+简单来说,平均负载是指单位时间内,系统处于__可运行状态__和__不可中断状态__的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
 
-所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
+所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
 
-不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态 (Uninterruptible Sleep,也称为 Disk Sleep)的进程。
+不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态 (Uninterruptible Sleep,也称为 Disk Sleep)的进程。
 
 比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是
 不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程

+ 11 - 12
zombie-process.md

@@ -1,6 +1,6 @@
 ## 什么是不可中断状态
 
-当 iowait 升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从 ps 或者 top 命令的输出中,可以发现它们都处于 D 状态,也就是不可中断状态 (Uninterruptible Sleep)
+当 iowait 升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从 ps 或者 top 命令的输出中,可以发现它们都处于 D 状态,也就是不可中断状态 (Uninterruptible Sleep)
 
 不可中断状态,表示进程正在跟硬件交互,为了保护进程数据和硬件的一致性,系统不允许其他进程或中断打断这个进程。进程长时间处于不可中断状态,通常表示系统有 I/O 性能问题。
 
@@ -10,8 +10,7 @@
 
 特别是,中断处理程序在响应中断时,还会临时关闭中断。这就会导致上一次中断处理完成之前,其他中断都不能响应,也就是说中断有可能会丢失。
 
-举个最常见的网卡接收数据包的例子:网卡接收到数据包后,会通过 __硬件中断__ 的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个 __软中断__ 信号,通知下半部做进一步的处理。而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据
-进行逐层解析和处理,直到把它送给应用程序。
+举个最常见的网卡接收数据包的例子:网卡接收到数据包后,会通过 __硬件中断__ 的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个 __软中断__ 信号,通知下半部做进一步的处理。而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。
 
 Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:
 
@@ -24,7 +23,7 @@ Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类
 
 ## 什么是僵死(僵尸)进程
 
-僵死(僵尸)进程进程:一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait() 或 waitpid() 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死(僵尸)。
+僵死(僵尸)进程:一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait() 或 waitpid() 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死(僵尸)。
 
 通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程退出后,由 init 进程回收后也会消亡。
 
@@ -32,7 +31,7 @@ Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类
 
 #### top 命令查看进程状态
 
-top 和 ps 是最常用的查看进程状态的工具,我们就从 top 的输出开始。下面是一个 top 命令输出的示例,S 列(也就是 Status 列)表示进程的状态。
+top 和 ps 是最常用的查看进程状态的工具,我们就从 top 的输出开始。下面是一个 top 命令输出的示例,S 列(也就是 Status 列)表示进程的状态。
 
 ```
 top - 21:43:31 up 28 days, 23:44,  2 users,  load average: 0.02, 0.02, 0.00
@@ -50,19 +49,19 @@ KiB Swap:        0 total,        0 free,        0 used.  3169024 avail Mem
     3 root      20   0       0      0      0 S   0.0  0.0   0:33.16 ksoftirqd/0
 ```
 
-- __R__ 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正 在等待运行。
+- __R__ 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
 
-- __D__ 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般 表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
+- __D__ 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
 
-- __Z__ 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它 表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)
+- __Z__ 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它 表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)
 
 - __S__ 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件 而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
 
-- __I__ 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件 交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升 高, I 状态的进程却不会。
+- __I__ 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
 
-- __T__ 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你 用 fg 命令,恢复到前台运行)。而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪 状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行。
+- __T__ 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你 用 fg 命令,恢复到前台运行)。而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行。
 
-- __X__ 是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令 中看到它。
+- __X__ 是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令中看到它。
 
 #### ps 命令查看进程状态
 
@@ -79,4 +78,4 @@ root     12913  0.0  0.0  12944   928 pts/1    S+   21:55   0:00 grep --color=au
 
 进程组和会话。它们用来管理一组相互关联的进程,进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;而会话是指共享同一个控制终端的一个或多个进程组。
 
-比如,我们通过 SSH 登录服务器,就会打开一个控制终端(TTY),这个控制终端就对应 一个会话。而我们在终端中运行的命令以及它们的子进程,就构成了一个个的进程组,其中,在后台运行的命令,构成后台进程组;在前台运行的命令,构成前台进程组。
+比如,我们通过 SSH 登录服务器,就会打开一个控制终端(TTY),这个控制终端就对应 一个会话。而我们在终端中运行的命令以及它们的子进程,就构成了一个个的进程组,其中,在后台运行的命令,构成后台进程组;在前台运行的命令,构成前台进程组。