communicating sequential processes (CSP)机制的提出非常古老(在1978年),它不同于erlang的actor model。go语言实现的CSP使用的通道会让消息的发送与接收更加解耦。
一、go语言的channel机制
1、阻塞式
接收者与发送者必须都在才能完成消息的发送与接收,如果发送者不在,接收者就必须等待,如果接收者不在,发送者也必须等待
2、非阻塞式
这种被称为buffer channel,是更加松耦合的实现方式,发送者与接收者各自独立,只要消息队列未满,发送者可以一直向channel中写入msg,只要消息队列不空,接收者可以一直从channel中取msg。
二、代码实现
串行执行
func service() string {
time.Sleep(time.Millisecond * 50)
return "Done"
}
func otherTask() {
fmt.Println("working on sth else")
time.Sleep(time.Millisecond * 100)
fmt.Println("Task is done")
}
func TestService(t *testing.T) {
fmt.Println(service())
otherTask()
}
输出:
Done
working on sth else
Task is done
使用channel改造成CSP:
func AsyncService() chan string {
retCh := make(chan string)
go func() {
ret := service()
fmt.Println("return result")
retCh <- ret
fmt.Println("service exited")
}()
return retCh
}
func TestAsyncService(t *testing.T) {
retCh := AsyncService()
otherTask()
fmt.Println(<-retCh)
time.Sleep(time.Second * 1)
}
执行结果:
working on sth else
return result
Task is done Done
service exited
由于是阻塞式的,所以发送者一直等接收者取走msg之后才退出,所有最后才打印"service exited"
改造成非阻塞式的:
func AsyncService() chan string {
retCh := make(chan string, 1)
go func() {
ret := service()
fmt.Println("return result")
retCh <- ret
fmt.Println("service exited")
}()
return retCh
}
输出结果:
working on sth else
return result
service exited
Task is done
Done
发送者完成消息发送就退出了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。