golang協程——通道channel阻塞


  新的一年開始了,不管今天以前發生了什么,向前看,就夠了。

  說到channel,就一定要說一說線程了。任何實際項目,無論大小,並發是必然存在的。並發的存在,就涉及到線程通信。在當下的開發語言中,線程通訊主要有兩種,共享內存與消息傳遞。共享內存一定都很熟悉,通過共同操作同一對象,實現線程間通訊。消息傳遞即通過類似聊天的方式。golang對並發的處理采用了協程的技術。golang的goroutine就是協程的實現。協程的概念很早就有,簡單的理解為輕量級線程,goroutine就是為了解決並發任務間的通信而設計的。golang解決通信的理念是:不要通過共享內存來通信,而應該通過通信來共享內存。golang解決方案是消息傳遞機制,消息的傳遞就是通過channel來實現的。

  channel的使用很簡單,這里就不在粘別人的東西了。現在談一談對channe阻塞l的理解。  

  發送者角度:對於同一個通道,發送操作(協程或者函數中的),在接收者准備好之前是阻塞的。如果chan中的數據無人接收,就無法再給通道傳入其他數據。因為新的輸入無法在通道非空的情況下傳入。所以發送操作會等待 chan 再次變為可用狀態:就是通道值被接收時(可以傳入變量)。

  接收者角度:對於同一個通道,接收操作是阻塞的(協程或函數中的),直到發送者可用:如果通道中沒有數據,接收者就阻塞了。

  通過一個簡單的例子來說明:

  

 1 package main
 2 
 3 import (
 4     "fmt"
 5 )
 6 
 7 func f1(in chan int) {
 8     fmt.Println(<-in)
 9 }
10 
11 func main() {
12     out := make(chan int)
13     out <- 2
14     go f1(out)
15 }

  運行結果:fatal error: all goroutines are asleep - deadlock!

  這是由於第13行之前不存在對out的接收,所以,對於out <- 2來說,永遠是阻塞的,即一直會等下去。

  將13,14行互換

 1 package main
 2 
 3 import (
 4     "fmt"
 5 )
 6 
 7 func f1(in chan int) {
 8     fmt.Println(<-in)
 9 }
10 
11 func main() {
12     out := make(chan int)
13     go f1(out)
14     out <- 2
15 }

  運行結果:2

  14行前存在對管道的讀操作,所以out <- 2 是合法的。就像前文說的,發送操作在接收者准備好之前是阻塞的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM