【霏艺所思】什么是反应器(Reactor)和前摄器(Proactor)?

使用CN2/CN2GIA顶级线路,支持Shadowsocks/V2ray科学上网,支持支付宝付款,每月仅需 5 美元
## 加入品葱精选 Telegram Channel ##

我已经说了**,我不想继续讨论翻墙的事情。。。**

# 什么是同步?什么是异步?
这种基本概念,其实网上一堆。。。我再来一次吧!
我给 XXX 打了一个电话,这个就是同步消息!
我给 XXX 寄了一封邮件,这个就是异步消息!
怎么理解呢?
打电话,我和 XXX 的通信 是 “实时”的,我说的内容, XXX 可以即时收到,体现了“实时性”。
发邮件,我和 XXX 的通信 不是 “实时”的!我寄完信,根本不知道 XXX 会不会去读,甚至无法知道他能不能收到!

# 什么是CSP?什么是Actor?
这种基本概念,其实网上一堆。。。我再来一次吧!
继续用寄信给你们举例子!
寄信,要信箱!这个能理解吧?
Actor模型
如果每个收信人,都有自己的独立信箱,这个就是actor模型。
每个收信人都是一个Actor,他们有自己独立的信箱。
其他Actor作为发信人,通过 向其他Actor的信箱寄信,完成消息传递。
代码大概长这样
```伪代码
发信人 = new Actor()
收信人 = new Actor()
邮递员 = new ActorManager()

发信人告诉邮递员自己的信箱地址
收信人告诉邮递员自己的信箱地址
邮递员。派发信件(发信人,收信人,信件)
```
CSP模型
不是按人来设置信箱,而是根据事情。
比如,我投诉戴尔电脑某某问题,就给戴尔寄信,但是我不知道戴尔的哪个员工会收到。
再比如,我给微软提bug,我也不知道哪个人可以收到我的信。
也就是说某类人可以共用一个信箱
```伪代码
微软的信箱 = new MailBox()

戴尔的信箱 = new MailBox()
邮递员 = new ActorManager()

邮递员。派发信件(我,微软的信箱,信件)
```
和Actor的区别
每个Actor都有自己的独立信箱!
CSP的话,n个Actor共用一个信箱。。。

# 什么是反应器?什么是前摄器?
这种基本概念,其实网上一堆。。。我再来一次吧!
先把线程分两类
1. 处理器 handler【你自己实现的业务代码逻辑实现】
2. 分离器 evloop 【调用select poll epoll iocp kqueue的线程】

反应器模式
IO操作【读/写操作】,
如果在handler线程,就是反应器模式!
如果在evloop线程,就是前摄器模式!

反应器模式举例:
eventMap = new Map<event, func>
evloop线程 通过 select/poll/epoll等判断有什么event
如果有发生event,就把对应的func 放到handler的信箱里
handler不停访问自己的信箱,取出信箱里的func并调用【这个func都是IO操作,所以IO操作在handler线程】

前摄器模式举例:
eventMap = new Map<event, func>
handler调用IO操作的时候,没有直接操作
而是把对应的IO操作,放到evloop的信箱里
evloop线程 通过 select/poll/epoll等判断有什么event
然后把对应的event取出来,去自己的信箱里找到对应的func并执行【IO操作在evloop线程】

至于信箱是用CSP模型,还是Actor模型,是没有指定的。。。你们随意,喜欢就好~

以上都是“单进程多线程模式”的讨论!
如果是多进程,甚至多服务器。其实道理是类似的。。。
你可以这么理解多进程/多服务器的CSP
CSP的信箱,可以是一个数据库【Oracle,MySQL】,也可以是一个消息队列【RabbitMQ,Kafka】

==========================
我也不知道,你们听懂了没有。。。没听懂就留言吧
我会解答的

品葱用户 霏艺Faye 评论于 2020-06-03

小丑鱼架构模型:
简介:小丑鱼是一种可以改变性别的鱼。
正常情况下,一个小丑鱼的鱼群里有雄鱼和雌鱼。
如果这群鱼里,只有雄鱼那么神奇的事情发生了
雄鱼们会开始选举,选举它们中的一条鱼变成雌鱼

nginx的架构模型就是小丑鱼!
正常情况下,nginx有一个master进程和n个worker进程。
worker进程,都是具体干活的,死了一个也不会导致nginx服务出现中断,因为还有其他的worker进程继续工作。而且master进程,就像雌鱼,会生孩子!会自己重新fork一个worker进程。。。。

如果挂掉的是master进程,那么就会在存活的worker进程里,选举一个成为master进程,然后就继续稳定提供服务,百分百完备的不会中断服务!

总结:
1.如果是worker进程挂了,其他worker会分担它的工作,master进程会fork新的worker顶替它。
2.如果是master进程挂了,worker进程会选举一个成为新的master,然后新的master会fork一个新的worker。

master就是 雌性的小丑鱼,可以生孩子。
worker就是 雄性的小丑鱼,雌鱼死了,会被选举成心的雌鱼!

品葱用户 霏艺Faye 评论于 2020-06-02

一句话总结:
反应器模式:evloop把“IO操作”放到handler的信箱。
前摄器模式:handler把“IO操作”放到evloop的信箱。
-—————————-
反应器模式,由于IO操作在handler线程,所以IO阻塞会导致业务代码无法运行
不是很建议在网络不好的环境下使用反应器模式
-—————————-
另外,一个进程起多少线程问题
我自己的建议是 看你cpu多少核吧
假设是AMD那种 32核64线程的,就起64个线程
如果没有超线程的CPU,比如老的i5,4核4线程,就老老实实4个线程。。。
也不绝对。。。
好多开源项目,我看高并发的时候都4000多线程了。。。。
-—————————-
windows下,建议“单进程多线程”,因为windows下进程上下文切换很慢,但是线程上下文切换很快!
linux下,建议“多进程单线程”,因为linux下进程和线程上下文切换开销差不多!但是一个线程挂了,整个进程就挂了!一个进程挂了不会影响其他进程!所以多进程有更好的稳定性!

点击品葱原文参与讨论

最简单好用的 VPS,没有之一,注册立得 100 美金
comments powered by Disqus

See Also