【每日一题】Node进程间通信

前端印记

共 2335字,需浏览 5分钟

 ·

2021-09-17 19:45

人生苦短,总需要一点仪式感。比如学前端~

进程间通信分类

每个进程都有各自不同的用户地址空间,任何一个进程的全局变量在另一个进程中看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一个缓存区,进程 A 把数据从用户空间拷贝到内核缓存区,进程 B 再从该缓冲区把数据读走,内核提供的这种机制称为进程间通信

实现进程间通信(IPC)的方式

匿名通道

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系”的进程间调用。进程的亲缘关系通常是指父子进程关系。

半双工通信:支持数据在两个方向上互相传输,可以实现双向通信。但同一时刻只允许数据在一个方向上传输。比如对讲机的模式。

有点类似vue中props之于父子组件的存在。

命名管道

命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间通信

有点类似vue中 中央总线 的存在。

信号量

信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间同步的手段。

消息队列

消息队列是由消息的链表存放在内核中并由消息队列标识符标识。

消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓存区大小受限等缺点。

信号

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生

共享内存

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

共享内容是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信。

套接字

套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信

从技术上可以划分四种:

  1. 【消息传递】:管道、FIFO、消息队列
  2. 【同步】:互斥量、条件变量、读写锁等
  3. 【共享内存】:匿名的、命名的
  4. 【远程过程调用】

node 进程间通信方式

nodeIPC 通过通道技术 + 事件循环方式进行通信。

管道技术在 Windows 下由命名管道实现;
在*nix系统则由 Unix Domain Socket 实现,提供给我们简单的 message事件send方法

我们通过on('message',function(m,setHandle){})send(message,[sendHandle])来实现IPC。

Node中父子进程的IPC通道建立

父进程和子进程之间建立 IPC 通道

child_process.spawn(command[, args][, options])

child_process.spawn() 方法使用给定的 command 和 args 中的命令行参数衍生新进程。

可通过配置options.stdio来指定额外的文件描述符以在父进程和子进程之间创建额外的管道。

child_process.fork()

child_process.fork() 方法是 child_process.spawn() 的特例,专门用于衍生新的 Node.js 进程。与 child_process.spawn() 一样,返回 ChildProcess 对象。返回的 ChildProcess 将有额外的内置通信通道,允许消息在父进程和子进程之间来回传递。详见 subprocess.send()
http://nodejs.cn/api/child_process.html#child_process_child_process_fork_modulepath_args_options

管道

管道实际上是在内核中开辟一块缓冲区,它有一个读端、一个写端,并传给用户程序两个文件描述符,一个指向读端,一个指向写端。然后该缓冲存储不同进程间写入的内容,并供不同进程读取内容,进而达到通信的目的。

管道又分为匿名管道命名管道
匿名管道常见于一个进程fork出一个子进程,只能亲缘进程通信;
而命名管道可以让非亲缘进程进行通信。

其实本质上来说进程间通信是利用内核管理一块内存,不同进程可以读写这块内容,进而可以互相通信。

文件描述符

在 linux 中一切皆文件,linux 会给每个文件分配一个 id,这个 id 就是文件描述符,指针也是文件描述符的一种。这个很好理解,不过我们可以深入说说,一个进程启动后,会在内核空间(虚拟空间的一部分)创建一个 PCB 控制块,PCB 内部有一个文件描述符表,记录着当前进程所有可用的文件描述符(即当前进程所有打开的文件)。系统除了维护文件描述符表外,还需要维护打开文件表(Open file table)和 i-node(i-node table)

文件打开表(Open file table)包含文件偏移量,状态标志,i-node表指针等信息

i-node 表(i-node table)包括文件类型、文件大小、时间戳、文件锁等信息

文件描述符不是一对一的,它可以:

  • 同一进程的不同文件描述符指向同一文件
  • 不同进程可以拥有相同的文件描述符---比如 fork 出的子进程拥有父进程一样的文件描述符,或者不同进程打开同一文件
  • 不同进程的同一文件描述符也可以指向不同的文件
  • 不同进程的不同文件描述符也可以指向同一个文件

END
愿你历尽千帆,归来仍是少年。


让我们一起携手同走前端路!

关注公众号回复【加群】即可

浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报