Golang 並發concurrency

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

並發concurrency

  • 很多人都是衝著Go大肆宣揚的高並發而忍不住躍躍欲試,但其實從源碼解析來看,goroutine只是由官方實現的超級“線程池”而已。不過話說回來,每個執行個體4-5KB的棧記憶體佔用和由於實現機制而大幅減少的建立和銷毀開銷,是製造Go號稱的高並發的根本原因。另外goroutine的簡單易用,也在語言層面上給予了開發人員的巨大的便利。
    並發不是並行 Concurrency Is Not Parallelism
  • 並發主要由切換時間片來實現“同時”運行,在並行則是直接利用多核實現多線程的運行,但Go可以設定使用核心數,以發揮多核電腦的能力
  • Goroutine 奉行通過通訊來共用記憶體,而不是共用記憶體來通訊。

Channel

  • Channel 是 goroutine 溝通的橋樑,大都是阻塞同步的
  • 通過 make 建立,close 關閉
  • Channel 是參考型別
  • 可以使用 for range 來迭代不斷操作 channel
  • 可以設定單向或雙向通道
  • 可以設定緩衝大小,在未被填滿前不會發生阻塞

通過 make 建立,close 關閉

package mainimport (    "fmt")func main() {    c := make(chan bool) //聲明一個channel    go func() {        fmt.Println("GOOD---")        c <- true //存入這個channel    }()    <-c //取出這個channel    //當這個main函數執行的時候,遇到gorouting時會直接執行到<-c,此時這個程式會阻塞,一直等到有true存入這個channel(c<-true),此時(<-c)才能讀出來,main函數完成}

可以使用 for range 來迭代不斷操作 channel

package mainimport (    "fmt")func main() {    c := make(chan bool)    go func() {        fmt.Println("GOOD---")        c <- true        close(c) //關閉這個channel,迭代操作會終止    }()    for v := range c {        fmt.Println(v)    }}

可以設定緩衝大小,在未被填滿前是非同步,不會發生阻塞

package mainimport (    "fmt"    "runtime")func main() {    runtime.GOMAXPROCS(runtime.NumCPU()) //1.8預設使用多核CPU    c := make(chan bool, 10)    for i := 0; i < 10; i++ {        go Go(c, i)    }    for i := 0; i < 10; i++ {        <-c    }}func Go(c chan bool, index int) {    a := 1    for i := 0; i < 1000000; i++ {        a += i    }    fmt.Println(index, a)    c <- true}/*如果設定了緩衝大小,大小在未被填滿之前,它是非同步,不會發生阻塞如果這個channel沒有緩衝的話,要注意取出的操作要在寫入的操作的前面*/
package mainimport (    "fmt"    "runtime"    "sync")func main() {    runtime.GOMAXPROCS(runtime.NumCPU()) //1.8預設使用多核CPU    wg := sync.WaitGroup{}    wg.Add(10)    for i := 0; i < 10; i++ {        go Go(&wg, i)    }    wg.Wait() //通過同步包來實現多個gorouting同步內容}func Go(wg *sync.WaitGroup, index int) {    a := 1    for i := 0; i < 1000000; i++ {        a += i    }    fmt.Println(index, a)    wg.Done()}/*如果設定了緩衝大小,大小在未被填滿之前,它是非同步,不會發生阻塞如果這個channel沒有緩衝的話,要注意取出的操作要在寫入的操作的前面*/

Select

  • 可處理一個或多個 channel 的發送與接收
  • 同時有多個可用的 channel時按隨機順序處理
  • 可用空的 select 來阻塞 main 函數
  • 可設定逾時
package mainimport (    "fmt")func main() {    c1, c2 := make(chan int), make(chan string)    o := make(chan bool)    go func() {        for {            select {            case v, ok := <-c1:                if !ok {                    o <- true                    break                }                fmt.Println("c1", v)            case v, ok := <-c2:                if !ok {                    o <- true                    break                }                fmt.Println("c2", v)            }        }    }()    c1 <- 1    c2 <- "hi"    c1 <- 3    c2 <- "hello"    close(c1)    close(c2)    <-o}

select設定逾時

package mainimport (    "fmt"    "time")func main() {    c := make(chan bool)    select {    case v := <-c:        fmt.Println(v)    case <-time.After(3 * time.Second): //返回的是一個time類型的chan        fmt.Println("TimeOut")    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.