作为一名合格的程序猿/媛,对于进程、线程还是有必要了解一点的,本文将从下面几个方向进行梳理,尽量做到知其然并知其所以然:



  • 进程和线程的概念和关系

  • 进程演进

  • 进程间通信

  • 理解底层基础,助力上层应用

  • 进程保护


进程和线程的概念和关系



用户下达运行程序的命令后,就会产生进程。同一程序可产生多个进程(一对多关系),以允许同时有多位用户运行同一程序,却不会相冲突。




进程需要一些资源才能完成工作,如CPU使用时间、存储器、文件以及I/O设备,且为依序逐一进行,也就是每个CPU核心任何时间内仅能运行一项进程。




进程与线程的区别:进程是计算机管理运行程序的一种方式,一个进程下可包含一个或者多个线程。线程可以理解为子进程。




摘自wiki百科



也就是说,进程是我们运行的程序代码和占用的资源总和,线程是进程的最小执行单位,当然也支持并发。可以说是把问题细化,分成一个个更小的问题,进而得以解决。


并且进程内的线程是共享进程资源的,处于同一地址空间,所以切换和通信相对成本小,而进程可以理解为没有公共的包裹容器


但是如果进程间需要通信的话,也需要一个公共环境或者一个媒介,这个就是操作系统。


进程演进


我们的计算机有单核的、多核的,也有多种的组合方式:



  1. 单进程


因为是一个进程,所以某一时刻只能处理一个事务,后续需要等待,体验不好



  1. 多进程


为了解决上面的问题,但是如果有很多请求的话,会产生很多进程,开销本身就是一个不小的问题,而进程占据独立的内存,这么多响应是的进程难免会有重复的状态和数据,会造成资源浪费。



  1. 多进程多线程


由之前的进程处理事务,改成使用线程处理事务,解决了开销大,资源浪费的问题,还可以使用线程池,预先创建就绪线程,减少创建和销毁线程的开销。


但是一个cpu某一时刻只能处理一个事务。像时间分片来调度线程的话,会导致线程切换频繁,是非常耗时的。



  1. 单进程单线程


类似也就是v8,基于事件驱动,有效的避免了内存开销和上下文切换,只需要线程间通信,即可在适当的时刻进行事务结果等的反馈。


但是遇到计算量很大的事务,会阻塞后续任务的执行。像这样:


node进程间通信



  1. 单进程单线程(多进程架构)


node提供了clusterchild_process两个模块进行进程的创建,也就是我们常说的主(Master)从(Worker)模式。Master负责任务调度和管理Worker进程,Worker进行事务处理。


node进程间通信


文档。

常见的异步方法有:



  1. .exec

  2. .execFile

  3. .fork

  4. .spawn


除了fork出来的进程会长期驻存外,其他方式会在子进程任务完成后以流的方式返回并销毁进程。


异步方法会返回ChildProcess的实例,ChildProcess不能直接创建,只能返回。


来看几张图吧:


node进程间通信


node进程间通信


node进程间通信


进程间通信(IPC)大概有这几种:

  • 匿名管道

  • 命名管道

  • 信号量

  • 消息队列

  • 信号

  • 共享内存

  • 套接字


从技术上划分又可以划分成以下四种:



  1. 消息传递(管道,FIFO,消息队列)

  2. 同步(互斥量,条件变量,读写锁等)

  3. 共享内存(匿名的,命名的)

  4. 远程过程调用


文件描述符是什么?


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


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


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


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



  1. 同一进程的不同文件描述符指向同一文件

  2. 不同进程可以拥有相同的文件描述符(比如fork出的子进程拥有和父进程一样的文件描述符,或者不同进程打开同一文件)

  3. 不同进程的同一文件描述符也可以指向不同的文件

  4. 不同进程的不同文件描述符也可以指向同一个文件


上面提及了很多可以实现进程间通信的方式,那node进程间通信是以什么为基础的呢?


nodeIPC通过管道技术 加 事件循环方式进行通信,管道技术在windows下由命名管道实现,在*nix系统则由Unix Domain socket实现,提供给我们的是简单的message事件和send方法。


那管道是什么呢?


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


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


node进程间通信


其实本质上来说进程间通信是利用内核管理一块内存,不同进程可以读写这块内容,进而可以互相通信,当然,说起来简单,做起来难。有兴趣的朋友可以自行研究。


pm2是对cluster的一种封装,提供了:

  • 内奸负载均衡

  • 后台运行

  • 停机重载

  • 具有Ubuntu、CentOS的启动脚本

  • 停止不稳定的进程

  • 控制台检测

  • 有好的可视化界面


具体原理和细节以后有空再做分析。



文中若有错误的地方,欢迎指出,我会及时更新。希望读者借鉴的阅读。



IPC2

相关文章:

猜你喜欢
  • 2022-12-23
  • 2021-07-08
  • 2021-10-06
  • 2021-05-15
相关资源
相似解决方案