本文介绍多种并发模型包括锁、STM 、CSP 、Actor 及 I/O 多路复用等,还有对 Java 、Go 、Erlang/Elixir 与 Clojure 等对这些模型的实现的介绍。
编程的两大安全难题是线程安全与内存安全。这个系列的两篇文章都是在尝试介绍不同编程语言是如何解决线程安全从而更容易的实现高并发。
文章地址: https://www.bmpi.dev/dev/deep-in-program-language/how-to-implement-concurrency/concurrency-model/
1
oxykr 2022-05-28 09:35:24 +08:00
感谢分享
|
2
SoulSleep 2022-05-28 10:04:36 +08:00
图用什么工具做的 在很多地方看到过,感觉非常适合做技术拆解
|
4
NeroKamin 2022-05-28 12:51:03 +08:00 via iPhone 4
@SoulSleep 应该是 excalidraw.com
|
5
a90120411 2022-05-28 19:33:59 +08:00
好文章!
|
6
yazoox 2022-05-31 22:33:22 +08:00 via Android
好像很厉害的样子
|
7
Pythondr 2022-06-07 19:53:53 +08:00
写的不错,受益匪浅
|
8
superchrisliu 2022-06-20 15:42:27 +08:00
各位大佬,请教一下:
在 netty eventloop 中,一个连接所有的 read ,write 操作都在一个线程中,也就是连接 channel 是和线程绑定的,这样,没有线程切换的问题,对一个连接来说也不需要共享内存,因为都在一个线程中。而在 vertx 这样的 actor 模型中,为什么不把一个连接和线程绑定呢,比如,vertx 作为 http 服务,接受一个请求,发出查询 redis 请求,查询的结果处理 callback 就不是在发出请求的线程了,这样会有线程切换,为什么 actor 实现是这样的。 如果我用 netty 作为 http 服务,接受请求,之后查询 redis 也是使用 netty 的编解码器,那么从接受 http 请求,到发出 redis 查询请求,再到 redis 返回结果处理,再把结果返回给客户端,整个流程都在一个线程中的,没有线程切换,数据共享的问题 actor 模型跟 netty 的 eventloop 比哪种好?为什么? |
9
bmpidev2019 OP @superchrisliu eventloop 这种是利用多路复用的 I/O 模型去实现高并发,在请求被分发给 handler 后依旧可能利用多线程去处理代理请求(比如这个 request 里又请求了其他服务的 API ),所以并不是到 handler 之后就同步处理了,需要看实际的场景啊。actor 模型更复杂一些,但它可以跨节点去通信,适合分布式的场景。至于线程切换,如果是用户线程的话,切换开销不高,应该比同步等待 I/O 模型的数据开销都低。
|
10
superchrisliu 2022-06-20 16:16:34 +08:00
@bmpidev2019 在请求被分发给 handler 后依旧可能利用多线程去处理代理请求(比如这个 request 里又请求了其他服务的 API )----------老哥,看来你没太明白啊,这个 request 里又请求了其他服务的 API ,假设是 http 调用其他服务吧,那么这个 http 调用的 client 也是用 netty 实现的,同时这个 http client (使用 netty 实现的 client ,是可以自己指定 eventloop 线程的)和 request 所在线程 eventloop 使用同一个(这里是重点),所以你举的这个例子,不涉及多线程问题,只有一个线程
|
11
bmpidev2019 OP @superchrisliu 我知道你的意思,你说的只是 netty 那么做的,和实现的场景相关,我既可以在同一个线程也可以不在,至于你的困惑是为何 actor 模型要切换线程做,因为线程切换有开销。但 actor 模型的代表是 erlang 语言,erlang 实现了一个非常高效的用户线程调度模型,线程切换开销极低。
|