nodejs遵循的是单线程单进程的模式
它是基于事件驱动、异步非阻塞模式的。
- Node的单线程是指JS的引擎只有一个实例,且在nodejs的主线程中执行,同时node以事件驱动的方式处理IO等异步操作。
- Node的单线程模式,只维持一个主线程,大大减少了线程间切换的开销,但是会有多个worker线程,用于执行异步操作。
- Node的单线程使得在主线程不能进行CPU密集型操作,否则会阻塞主线程。
- 对于CPU密集型操作,在node中通过 child_process 可以创建独立的子进程,父子进程通过IPC通信,子进程可以是外部应用也可以是node子程序,子进程执行后可以将结果返回给父进程。
目录
Node提供了 child_process 模块,同时提供了 child_process.fork() 函数实现进程复制。
Master-Worker模式
典型的分布式架构中用于并行处理业务的模式,具备较好的可伸缩性和稳定性。
通过fork() 复制的进程都是一个独立的进程,这个进程具有着独立而全新的V8实例。
它至少需要30ms启动和至少10MB的内存。为此fork()进程是昂贵的。
好在Node通过事件驱动的方式在单线程上解决了大并发的问题,这里启动多个进程只是为了充分将CPU资源利用起来,而不是为了解决并发问题。
方法 | 描述 |
spawn() | 启动一个子进程来执行命令 |
exec() | 启动一个子进程来执行命令,与spawn() 不同的是其接口不同,它有一个回调函数获知子进程的状况 |
execFile() | 启动一个子进程来执行文件 |
fork() | 与spawn() 类似,不同点在于它创建Node的子进程只需指定要执行的JS文件模块既可 |
spawn() 与 exec()、execFile()不同的是,后两者创建时可以指定timeout属性设置超时事件,一旦创建的进程运行超过设定的时间将会被杀死。
exec() 与 execFile() 不同的时,exec() 适合执行已有的命令,execFile() 适合执行文件
- var cp = require('child_process');
- cp.spawn('node', ['worker.js']);
-
- cp.exec('node worker.js', fucntion (err, stdout, stderr){
- // funciton
- });
-
- cp.execFile('worker.js', function (err, stdout, stderr){
- // funciton
- });
-
- cp.fork('./worker.js');
通过fork() 或者其他API,创建子进程后,为了实现父子进程之间的通信,父子进程之间将会创建IPC通道并使用message和send()传递消息。
IPC —— Inter-Process Communication,进程间通信。
目的是为了让不同的进程能够相互访问资源并进行协调工资,Node使用的技术是管道(pipe)技术 (着仅仅是字面上的称呼,和传统的不一样,具体细节实现由libuv提供)
在Windows下由命名管道(named pipe)实现,Linux则使用 Unix Domain Socket 实现。表现在应用层上的进程间通信只有简单的message事件和send()方法。
只有启动的子进程是Node进程时,子进程才会根据环境变量去连接IPC通道,对于其他类型的子进程则无法实现进程间通信,除非其他进程也按约定去连接这个已经创建好的IPC通道。