关于 Process, 我们需要讨论的是两个概念, ①操作系统的进程, ② Node.js 中的 Process 对象. 操作进程对于服务端而言, 好比 html 之于前端一样基础. 想做服务端编程是不可能绕过 Unix/Linux 的. 在 Linux/Unix/Mac 系统中运行 ps -ef 命令可以看到当前系统中运行的进程. 各个参数如下:

clipboard.png

clipboard.png

常见api

Node.js 中的 process 对象. 直接在代码中通过 console.log(process) 即可打印出来. 可以看到 process 对象暴露了非常多有用的属性以及方法, 具体的细节见官方文档, 已经说的挺详细了. 其中包括但不限于:

  • 进程基础信息
  • 进程 Usage
  • 进程级事件
  • 依赖模块/版本信息
  • OS 基础信息
  • 账户信息
  • 信号收发
  • 三个标准流

官方文档: https://nodejs.org/api/proces...

process是一个 global全局对象
提供有关信息,控制当前 Node.js 进程。作为一个对象,它对于 Node.js 应用程序始终是可用的,故无需使用 require()

process 这个对象是EventEmitter的实例。

process.env.NODE_PATH

获取到在系统中环境变量设置的内容:

图片描述
图片描述
__dirname:获取到当前文件所在的路径:

process.nextTick

图片描述

图片描述

   ┌───────────────────────┐
┌─>│        timers         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<─────┤  connections, │
│  └──────────┬────────────┘      │   data, etc.  │
│  ┌──────────┴────────────┐      └───────────────┘
│  │        check          │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │
   └───────────────────────┘

process.nextTick 并不属于 Event loop 中的某一个阶段, 而是在 Event loop 的每一个阶段结束后, 直接执行 nextTickQueue 中插入的 "Tick", 并且直到整个 Queue 处理完.

具体的api照着文档看

标准输入输出流

在 process 对象上还暴露了 process.stderr, process.stdout 以及 process.stdin 三个标准流, 熟悉 C/C++/Java 的同学应该对此比较熟悉.

console.log 是同步还是异步?

console.log既不是总是同步的,也不总是异步的。是否为同步取决于链接的是什么流以及操作系统是Windows还是POSIX:

注意: 同步写将会阻塞事件循环直到写完成。 有时可能一瞬间就能写到一个文件,但当系统处于高负载时,管道的接收端可能不会被读取、缓慢的终端或文件系统,因为事件循环被阻塞的足够频繁且足够长的时间,这些可能会给系统性能带来消极的影响。当你向一个交互终端会话写时这可能不是个问题,但当生产日志到进程的输出流时要特别留心。

  • 文件(Files): Windows和POSIX平台下都是同步
  • 终端(TTYs): 在Windows平台下同步,在POSIX平台下异步
  • 管道(Pipes): 在Windows平台下同步,在POSIX平台下异步
如何实现一个 console.log?

实现console.log在控制台打印,利用process.stdout将输入流数据输出到输出流(即输出到终端),一个简单的例子输出hello world process.stdout.write('hello world!' + 'n');,以下例子是对console源码解读实现,将Console取名为Logger。
https://www.imooc.com/article...

A note on process I/O

图片描述图片描述

这里来做个计算器实例:

图片描述

跨系统

node.js提供了 os.platform() 或者 process.platform 来检测当前系统

os.platform 或 process.platform  返回
 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'

图片描述

[多进程架构]

Node 的线程池

在 Node 中有一些 IO 操作(DNS,FS)和一些 CPU 密集计算(Zlib,Crypto)会启用 Node 的线程池,而线程池默认大小为 4

手动更改线程池默认大小:

process.env.UV_THREADPOOL_SIZE = 64

cluster

cluster 是多线程吗?

Node 的单线程也带来了一些问题,比如对 cpu 利用不足,某个未捕获的异常可能会导致整个程序的退出等等。因为 Node 中提供了 cluster 模块,cluster 实现了对 child_process 的封装,通过 fork 方法创建子进程的方式实现了多进程模型。比如我们最常用到的 pm2 就是其中最优秀的代表。

clipboard.png
一共有 9 个进程,其中一个主进程,cpu 个数 x cpu 核数 = 2 x 4 = 8 个 子进程。 numCPUs = 8

所以无论 child_process 还是 cluster,都不是多线程模型,而是多进程模型。虽然开发者意识到了单线程模型的问题,但是没有从根本上解决问题,而且提供了一个多进程的方式来模拟多线程。从前面的实验可以看出,虽然 Node (V8)本身是具有多线程的能力的,但是开发者并不能很好的利用这个能力,更多的是由 Node 底层提供的一些方式来使用多线程。Node 官方说:

You can use the built-in Node Worker Pool by developing a C++ addon. On older versions of Node, build your C++ addon using NAN, and on newer versions use N-API. node-webworker-threads offers a JavaScript-only way to access Node’s Worker Pool.

Node 10.5.0 的发布之前, 对于 JavaScript 开发者,一直没有一个标准的、好用的方式来使用 Node 的多线程能力。

worker_threads

Node 10.5.0 的发布,官方才给出了一个实验性质的模块 worker_threads 给 Node 提供真正的多线程能力。

jin

参考:

Node.js的进程管理:https://segmentfault.com/a/11...
饿了么 process
真-Node多线程


白鲸鱼
1k 声望110 粉丝

方寸湛蓝