Golang協程與通道整理

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。 協程goroutine
     不由OS調度,而是使用者層自行釋放CPU,從而在執行體之間切換。Go在底層進行協助實現     涉及系統調用的地方由Go標準庫協助釋放CPU     總之,不通過OS進行切換,自行切換,系統運行開支大大降低

通道channel
並發編程的關鍵在於執行體之間的通訊,go通過通過channel進行通訊channel可以認為類似其他OS體系中的訊息佇列,只不過在go中原生支援,因而易用
訊息佇列有哪些值得關注的地方?常見問題包括建立、關閉或刪除、阻塞、逾時、優先順序等,golang中也不例外。羅列如下:     可否探測隊列是滿或空?或者說是否可以不阻塞地嘗試讀寫?     讀阻塞和寫阻塞時關閉會怎樣?     關閉後未讀取的訊息會被拋棄?     往關閉的channel發送資料或讀取資料會怎樣?     怎樣探測channel的關閉?     兩個地方讀或寫阻塞同一個channel,有沒有優先順序?     是否可以設定阻塞的逾時時間?     阻塞時怎樣可以被彈出來?比如某些訊號?事實上,知道存在這些問題並進行分門別類是重要的,但知道這些問題的答案卻不緊要,因為一般不會太過古怪,使用時臨時實驗一下即可。
已知的部分答案:     好像不能不阻塞地嘗試讀寫     關閉會導致退出阻塞(似乎是一個不錯的特性)     可以探測關閉     channel本身不能設定逾時瞭解這些似乎已經足夠。

與眾不同的地方值得我們重點留意,包括:     除基本讀寫方式外,還有哪些特別的讀寫方式?在阻塞、關閉、逾時方面又有什麼不同?發現了select、range兩個關鍵字     推薦的多通道讀     推薦的同步方法     推薦的逾時方法


select
select可以實現無阻塞的多通道嘗試讀寫,以及阻塞逾時      var c, c1, c2, c3  chan  int var i1, i2  int
select {      case i1 = <-c1: //如果能走通任何case則隨機走一個         print( "received ", i1, " from c1\n" )      case c2 <- i2:         print( "sent ", i2, " to c2\n" )      case i3, ok := (<-c3):         if ok {                 print( "received ", i3, " from c3\n" )        }  else {                 print( "c3 is closed\n")        }      default: // 如果case都阻塞,則走default,如果無default,則阻塞在case        // default中可以不讀寫任何通道,那麼只要default提供不阻塞的出路,就相當於實現了對case的無阻塞嘗試讀寫         print( "no communication\n")}
實現阻塞逾時的方法是,只要不給default出路,而在case中實現一個逾時
timeout :=  make ( chan  bool, 1) go  func () {    time.Sleep(1e9) // 這是等待1秒鐘    timeout <-  true}() // 用timeout這個通道作為阻塞逾時的出路 select {   case <-ch:  // 處理從ch中讀到的資料   case <-timeout:  // 如果case都阻塞了,那麼1秒鐘後會從這裡找到出路} 

range
range可以在for迴圈中讀取channelGo文檔的翻譯文是:對於通道,其迭代值產生為在該通道上發送的連續值,直到該通道被關閉。若該通道為 nil,則range運算式將永遠阻塞經過實驗,range會阻塞,並且可以通過關閉channel來解除阻塞。
package main
import (       "fmt")
func main() {      ch :=  makechan  int )
        go  func () {              for i := 0; i < 10; i++ {                  ch <- i            }
      }()
              for w :=  range ch {            fmt.Println( "fmt print" , w)              if w > 5 {                   //break // 在這裡break迴圈也可以                    close(ch)            }      }      fmt.Println( "after range or close ch!" )}

Golang的並發編程還有其他細節,但以上是最主要脈絡。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.