大话 swoole 异步编程
遵从硬件不行软件来凑,出现了各种压榨CPU干活的异步编程技术。进程生死,一般遵循谁生谁管,当然儿子出问题(退出),会被告知老爸。没了爸了孩子(子进程)会被特殊进程收编。异步编程,通常是想好退路,被动的给别人执行。本文只是介绍一些与swoole相关的概念性的内容。
缘起
nodejs中称之为回调地狱,解决这种回调金字塔主要有以下几种方案
- EventProxy 事件发布订阅模式
- BlueBird Promise方案 (基本上是将嵌套调用变为水平调用)
- Async 异步流程控制库
select,poll,epoll,kqueue
之类的C事件库epoll
可以维持无限数量的连接,而且无需轮询select,poll
面临 循环检测连接是否有事件,假定只有一个连接可用,循环就极大浪费CPU (C10k问题出现)
- 生成器
- ES6原生有,python有,当然php也有,特点是需要显性的使用
yield
关键字 - 具备现场保存与返场的能力,让渡控制权 (与此类似C的万恶 goto 一样,跳来跳去)
- ES6原生有,python有,当然php也有,特点是需要显性的使用
异步/同步/阻塞/非阻塞
- 异/同步 与 阻塞 非阻塞 其实是站在 不同的角度上对同一事件的描述。
- 前者侧重是生产者如何拿到结果,后者则关注是消费者否可做其他的事。
白话就是,同步与异步关注你能不能等,能等就是异步,不能等现在立刻马上就要则是同步。非阻塞与阻塞,则是指你当前能不能做别的。后者出现的情况,常在当前的任务有依赖条件,没有了谁谁就不能继续进行,因此需要阻塞。而前者,则不一样,谁先谁后没关系,也不关心怎么来的,只要结果,当然这种情况下要求任务独立无依赖。
进程
进程本身不是基本的运行单位,而是线程的容器
-
具有动态性,并发性,异步性,结构性
- 独立性 与其他进程隔离
- 结构性 拥有代码段,数据段,PCB(进程控制块,包含进程的描述和控制信息)
-
父子进程
fork()
在当前进程创建一个新进程exec()
切换子进程中的执行程序- 正常情况下,父进程会收到两个返回值
exit
退了wait
获取子进程的退出状态,内核从内存中释放已结束子进程的PCB父子进程,也就一个
fork
生了,因此如果是原生php fork完毕,在子进程时pid 为0 (特别是通过循环产生子fork进程)时,需要且必须执行exit让子进程断子绝孙,否则子子孙孙无穷尽也....
-
组长/会话进程
setpgid()
加入一个现有的进程组或创建一个新进程组setsid
非组长进程建立新会话,该会话进程成为新组长进程- 每个进程被创建时,它便会成为父进程在session中的一员
- session主要是针对一个tty终端建立(与守护进程相关,因此守护进程的sessionid通常不能同终端一样)
- 在*unix中,组长进程不能创建会话,简单理解就是在组长进程中,执行setsid函数会报错
-
Linux特殊进程
- 0 调度进程,交换进程,系统进程
- 1 init 进程,内核调用,没有终端限制
swoole进程组件
- Master进程
- swoole 应用的root进程,
fork
出 Reactor线程和Manager进程 - Reactor 是包含在 Master 进程中的多线程程序,处理 TCP 连接和数据收发(异步非阻塞方式)
- swoole 应用的root进程,
- Manager进程
- Manager 进程负责 fork 并维护多个 Worker 子进程,负责回收并创建新的 Worker 子进程
- 当服务器关闭时,Manager 将发送信号给所有 Worker 子进程,通知其关闭服务
- Worker进程
- 以多进程方式运行,负责接受由 Reactor 线程投递的请求数据包
- 执行 PHP 回调函数,生成响应数据并发给 Reactor 线程
- Task Worker进程
- 同上,但仅用于任务分发,Task Worker 负责从队列中消费(同步阻塞方式处理)任务
swoole组件概念关系图
swoole官方经典话术
Swoole 官方对 Reactor、Worker、Task Worker有一个形象的比喻,如果把基于 Swoole 的 Web 服务器比作一个工厂,那么 Reactor 就是这个工厂的销售员,Worker 是负责生产的工人,销售员负责接订单,然后交给工人生产,而 Task Worker 可以理解为行政人员,负责提工人处理生产以外的杂事,比如订盒饭、收快递,让工人可以安心生产。
本作品采用《CC 协议》,转载必须注明作者和本文链接
点赞!!!