communicating sequential processes (CSP)機制的提出很是古老(在1978年),它不一樣於erlang的actor model。go語言實現的CSP使用的通道會讓消息的發送與接收更加解耦。spa
一、阻塞式code
接收者與發送者必須都在才能完成消息的發送與接收,若是發送者不在,接收者就必須等待,若是接收者不在,發送者也必須等待blog
二、非阻塞式隊列
這種被稱爲buffer channel,是更加鬆耦合的實現方式,發送者與接收者各自獨立,只要消息隊列未滿,發送者能夠一直向channel中寫入msg,只要消息隊列不空,接收者能夠一直從channel中取msg。消息隊列
串行執行string
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() }
輸出:it
Done
working on sth else
Task is done
使用channel改形成CSP:class
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) }
執行結果:test
working on sth else
return result
Task is done Done
service exited
因爲是阻塞式的,因此發送者一直等接收者取走msg以後才退出,全部最後纔打印"service exited"erlang
改形成非阻塞式的:
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
發送者完成消息發送就退出了