三分钟掌控Actor模型和CSP模型
回顾一下前文《三分钟掌握共享内存模型和 Actor模型》
Actor vs CSP模型
- 传统多线程的的共享内存(ShareMemory)模型使用lock,condition等同步原语来强行规定进程的执行顺序。
- Actor模型,是基于消息传递的并发模型,强调的是Actor这个工作实体,每个Actor自行决定消息传递的方向(要传递的ActorB),通过消息传递形成流水线。
本文现在要记录的是另一种基于消息传递的并发模型: CSP(communicating sequential process顺序通信过程)。
在CSP模型,worker之间不直接彼此联系,强调信道在消息传递中的作用,不谋求形成流水线。
消息的发送者和接受者通过该信道松耦合,发送者不知道自己消息被哪个接受者消费了,接受者也不知道是从哪个发送者发送的消息。
go的信道
go的信道是golang协程同步和通信的原生方式。
同map,slice一样,channel通过make内置函数初始化并返回引用。
两种信道:
- 无缓冲区信道:读写两端就绪后,才能通信(一方没就绪就阻塞)
这种方式可以用来在goroutine中进行同步,而不必显式锁或者条件变量。
- 有缓冲区信道:就有可能不阻塞, 只有buffer满了,写入才会阻塞;只有buffer空了,读才会阻塞。
go的信道暂时先聊到这里。
我们来用以上背景做一道 有意思的面试题吧 。
两个线程轮流打印0到100?
我不会啥算法,思路比较弱智:#两线程#, #打印奇/偶数#, 我先复刻这两个标签。
通过go的无缓冲信道的同步阻塞的能力对齐每一次循环。
package main import ( "fmt" "strconv" "sync" ) var wg sync.WaitGroup var ch1 = make(chan struct{}) func main() { wg.Add(2) go func() { defer wg.Done() for i := 0; i <= 100; i++ { ch1 <- struct{}{} if i%2 == 0 { // 偶数 fmt.Println("g0 " + strconv.Itoa(i)) } } }() go func() { defer wg.Done() for i := 0; i <= 100; i++ { <-ch1 if i%2 == 1 { // 奇数 fmt.Println("g1 " + strconv.Itoa(i)) } } }() wg.Wait() }
题解: 两个协程都执行0到100次循环,但是不管哪个线程跑的快,在每次循环输出时均会同步对齐, 每次循环时只输出一个奇/偶值, 这样也不用考虑两个协程的启动顺序。
我们来思考我的老牌劲语C#要完成本题要怎么做?
依旧是#两线程#、#打印奇偶数#。
volatile static int i = 0; static AutoResetEvent are = new AutoResetEvent(true); static AutoResetEvent are2 = new AutoResetEvent(false); public static void Main(String[] args) { Thread thread1 = new Thread(() => { for (var i=0;i<=100;i++) { are.WaitOne(); if (i % 2 == 0) { Console.WriteLine(i + "== 偶数"); } are2.Set(); } }); Thread thread2 = new Thread(() => { for (var i = 0; i <= 100; i++) { are2.WaitOne(); if (i % 2 == 1) { Console.WriteLine(i + "== 奇数"); } are.Set(); } }); thread1.Start(); thread2.Start(); Console.ReadKey(); }
注意两个:
- volatile:提醒编译器或运行时不对字段做优化(处于性能,编译器/runtime会对同时执行的线程访问的同一字段进行优化,加volatile忽略这种优化 )。
- Object-->MarshalByRefObject-->WaitHandle-->EventWaitHandle--->AutoResetEvent
本次使用了2个自动重置事件来切换通知,由一个线程通知另外一个线程执行。
本文来自博客园,作者:{有态度的马甲},转载请注明原文链接:https://www.cnblogs.com/JulianHuang/p/16056120.html
欢迎关注我的原创技术、职场公众号, 加好友谈天说地,一起进化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?