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
发送者完成消息发送就退出了