CSP和Actor
CSP
CSP的是Communicating Sequential Processes (CSP)
的缩写,翻译成中文是顺序通信进程。
CSP模型是上个世纪七十年代提出的,用于描述两个独立的并发实体通过共享的通讯channel(管道)进行通信的并发模型。 CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel。
Actor
Actor模式有一点类似面向对象模型,世界上所有的东西都被命名为Actor。单个Actor会拥有一些状态,比如为名字是cat
的Actor可能被描述为:
1 name : cat 2 age : 3 3 type : British shorthair 4 color : white 5 ....
到此为止好像和对象object没有什么不同,但是Actor不会给外界提供任何的行为接口.比如cat.Move()这是很自然的面向对象的写法,在Actor是不被允许的。每一个Actor的属性绝不对外暴露,想和外界进行通信必须发送message,所以每个Actor自身都有一个邮箱。
共同点
Don't communicate by sharing memory; share memory by communicating. (R. Pike)
Golang CSP
Golang 就是借用CSP模型的一些概念为之实现并发进行理论支持,其实从实际上出发,go语言并没有,完全实现了CSP模型的所有理论,仅仅是借用了process和channel这两个概念。process是在go语言上的表现就是 goroutine 是实际并发执行的实体,每个实体之间是通过channel通讯来实现数据共享。
Channel
Golang中使用 CSP中 channel 这个概念。channel 是被单独创建并且可以在进程之间传递,它的通信模式类似于 boss-worker 模式的,一个实体通过将消息发送到channel 中,然后又监听这个 channel 的实体处理,两个实体之间是匿名的,这个就实现实体中间的解耦,其中 channel 是同步的一个消息被发送到 channel 中,最终是一定要被另外的实体消费掉的,在实现原理上其实是一个阻塞的消息队列。
Goroutine
Goroutine 是实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,类似于 greenthread,go底层选择使用coroutine的出发点是因为,它具有以下特点:
- 用户空间:避免了内核态和用户态的切换导致的成本
- 可以由语言和框架层进行调度
- 更小的栈空间允许创建大量的实例
可以看到第二条用户空间线程的调度不是由操作系统来完成的,像在java 1.3中使用的greenthread的是由JVM统一调度的(后java已经改为内核线程),还有在ruby中的fiber(半协程) 是需要在重新中自己进行调度的,而goroutine是在golang层面提供了调度器,并且对网络IO库进行了封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。