單通道併發機制

communicating sequential processes (CSP)機制的提出很是古老(在1978年),它不一樣於erlang的actor model。go語言實現的CSP使用的通道會讓消息的發送與接收更加解耦。spa

1、go語言的channel機制

一、阻塞式code

channel.png

接收者與發送者必須都在才能完成消息的發送與接收,若是發送者不在,接收者就必須等待,若是接收者不在,發送者也必須等待blog

二、非阻塞式
buffer_channel.png隊列

這種被稱爲buffer channel,是更加鬆耦合的實現方式,發送者與接收者各自獨立,只要消息隊列未滿,發送者能夠一直向channel中寫入msg,只要消息隊列不空,接收者能夠一直從channel中取msg。消息隊列

2、代碼實現

串行執行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

發送者完成消息發送就退出了

相關文章
相關標籤/搜索