【Duke】CSP并发机制 023 - PingPongGooo/GoFoundation GitHub Wiki
CSP 并发机制
Communicating sequential processes
依赖于一个通道完成 两个通信实体之间的协调
CSP vs. Actor
和 Actor 的直接通讯不同,CSP模式则是通过Channel 进行通讯的, 更松耦合一些。
Go中 channel 是有容量限制并且独立于处理Groutine, 而如 Erlang,Actor模式中的 mailbox容量是无限的,接收进程也总是被动地处理消息。
Go 语言中地 Channel机制有两种
1. 通讯地双方必须同时在channel上才能完成本次地交互。任何一方不在地时候,另外一方就会阻塞,等待。知道,两方都在时。才完成交互。
2. buffer channel channel可以设置容量,容量在没有满地情况下,发送方可以放消息,当满了之后,发送方就需要等待,channel容量有空间,不然就会阻塞等待。 如果channel容量为空,接收消息地就会阻塞等待。
package csp
import (
"fmt"
"testing"
"time"
)
func service() string{
time.Sleep(time.Millisecond * 50) // 耗时操作
return "Done"
}
func otherTask() {
fmt.Println("working on something else")
time.Sleep(time.Millisecond * 100) // 延迟输出信息
fmt.Println("Task is done")
}
func TestService(t *testing.T) {
fmt.Println(service()) // 串行
otherTask()
}
串行输出 耗时 0.15s
=== RUN TestService
Done
working on something else
Task is done
--- PASS: TestService (0.15s)
PASS
// 第一种 channel 通信双方阻塞等待
func AsyncService() chan string { // 返回 channel
retCh := make(chan string) // 声明一个channel 指明 channel类型,放入string,就只能放string
go func() { // 1. 启动协程
ret := service()
fmt.Println("returned result")
retCh <- ret // 把结果放回到channel中
fmt.Println("service exited")
}()
return retCh
}
func TestAsyncService(t *testing.T){
retCh := AsyncService() // 另外一个任务。 放到另外一个协程中执行。
otherTask()
fmt.Println(<-retCh) // 当我们需要结果的时候,去channel中把数据读出来。
}
=== RUN TestAsyncService
working on something else
returned result
Task is done
Done
service exited
--- PASS: TestAsyncService (0.10s)
PASS
// 第2种 channel buff 当前设置为 1
func AsyncService2() chan string { // 返回 channel
retCh := make(chan string,1) // 声明一个channel 指明 channel类型,放入string,就只能放string //
go func() { // 1. 启动协程
ret := service()
fmt.Println("returned result")
retCh <- ret // 把结果放回到channel中
fmt.Println("service exited")
}()
return retCh
}
func TestAsyncService2(t *testing.T){
retCh := AsyncService2() // 另外一个任务。 放到另外一个协程中执行。
otherTask()
fmt.Println(<-retCh) // 当我们需要结果的时候,去channel中把数据读出来。
}
=== RUN TestAsyncService2
working on something else
returned result
service exited
Task is done
Done
--- PASS: TestAsyncService2 (0.10s)
PASS