首頁 >常見問題 >Go語言裡Channel相關解釋

Go語言裡Channel相關解釋

little bottle
little bottle轉載
2019-04-09 11:41:123084瀏覽

Go語言中使用了CSP模型來進行線程通信,準確地說,是輕量級線程goroutine之間的通信。 CSP模型和Actor模型類似,也是由獨立的,並發執行的實體所構成,實體之間也是透過發送訊息進行通訊的。

一.Actor模型與CSP模型區別:

Actor之間直接通訊,而CSP是透過Channel通訊,在耦合度上兩者是有差別的,後者更加鬆散耦合。
主要的差異在於:CSP模型中訊息的發送者和接收者之間透過Channel鬆耦合,發送者不知道自己訊息被哪個接收者消費了,接收者也不知道是哪個發送者發送的訊息。在Actor模型中,由於Actor可以根據自己的狀態選擇處理哪個傳入訊息,因此自主性可控性會比較好。
在Go語言中為了不阻塞進程,程式設計師必須檢查不同的傳入訊息,以便預見確保正確的順序。 CSP好處是Channel不需要緩衝訊息,而Actor理論上需要一個無限大小的郵箱作為訊息緩衝。
CSP模型的訊息發送方只能在接收方準備好接收訊息時才能發送訊息。相反,Actor模型中的消息傳遞是異步 的,即訊息的發送和接收無需在同一時間進行,發送方可以在接收方準備好接收訊息前將訊息發送出去。

二.Go Channel詳解
Channel類型的定義格式如下:

ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

它包含三種類型的定義。可選的<-代表channel的方向。如果沒有指定方向,那麼Channel就是雙向的,既可以接收數據,也可以發送數據。

chan T          // 可以接收和发送类型为 T 的数据
chan<- float64  // 只可以用来发送 float64 类型的数据
<-chan int      // 只可以用来接收 int 类型的数据

<-總是優先和最左邊的類型結合。 (The <- operator associates with the leftmost chan possible)

c := make(chan bool) //创建一个无缓冲的bool型Channel
c <- x        //向一个Channel发送一个值
<- c          //从一个Channel中接收一个值
x = <- c      //从Channel c接收一个值并将其存储到x中
x, ok = <- c  //从Channel接收一个值,如果channel关闭了或没有数据,那么ok将被置为false

預設情況下,channel發送方和接收方會一直阻塞直到對方準備好發送或者接收,這就使得Go語言無需加鎖或者其他條件,天然支持了並發。
使用make初始化Channel,並且可以設定容量:

make(chan int, 100) #//创建一个有缓冲的int型Channel

容量(capacity)代表Channel容納的最多的元素的數量,代表Channel的快取的大小。
如果沒有設定容量,或容量設定為0, 說明Channel沒有快取。
你可以在多個goroutine從/往 一個channel 中 receive/send 資料, 不必考慮額外的同步措施。
Channel可以作為一個先入先出(FIFO)的佇列,接收的資料和所傳送的資料的順序是一致的。
不含緩衝的Channel兼具通訊和同步兩種特性,在並發開發中頗受青睞。

// _Channels_ are the pipes that connect concurrent
// goroutines. You can send values into channels from one
// goroutine and receive those values into another
// goroutine.

package main

import "fmt"

func main() {

    // Create a new channel with `make(chan val-type)`.
    // Channels are typed by the values they convey.
    messages := make(chan string)

    // _Send_ a value into a channel using the `channel <-`
    // syntax. Here we send `"ping"`  to the `messages`
    // channel we made above, from a new goroutine.
    go func() { messages <- "ping" }()

    // The `<-channel` syntax _receives_ a value from the
    // channel. Here we&#39;ll receive the `"ping"` message
    // we sent above and print it out.
    msg := <-messages
    fmt.Println(msg)
}

這裡我們創建了一個沒有緩衝的string類型Channel,然後在一個goroutine把「ping」用channel<-傳給了這個Channel。 <-channel收到了這個值,然後在main函數列印出來。其實這裡我們利用Channel悄悄把「ping」message從一個goroutine轉移到了main goroutine,實現了線程間(準確的說,goroutine之間的)通訊。
因為channel發送方和接收方會一直阻塞直到對方準備好發送或接收,這就使得我們在程式末尾等」ping」 message而無需其他的同步操作。
再看一個範例:使用者自訂的goroutine完成某個操作之後提醒main goroutine:

// We can use channels to synchronize execution// across goroutines. Here&#39;s an example of using a// blocking receive to wait for a goroutine to finish.package mainimport "fmt"import "time"// This is the function we&#39;ll run in a goroutine. The// `done` channel will be used to notify another// goroutine that this function&#39;s work is done.func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")    // Send a value to notify that we&#39;re done.
    done <- true}func main() {    // Start a worker goroutine, giving it the channel to
    // notify on.
    done := make(chan bool, 1)    go worker(done)    // Block until we receive a notification from the
    // worker on the channel.
    <-done
}

           

################################################################################################ ###Go語言中使用了CSP模型來進行線程通信,準確地說,是輕量級線程goroutine之間的通信。 CSP模型和Actor模型類似,也是由獨立的,並發執行的實體所構成,實體之間也是透過發送訊息進行通訊的。 ######【推薦課程:###Go影片教學###】#######

以上是Go語言裡Channel相關解釋的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除