单通道并发机制

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

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

相关文章
相关标签/搜索