go中channel簡單使用

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

channel是go語言在語言層級提供的goroutine間的通訊機制。我們可以使用channel在兩個或者多個goroutine之間傳遞資訊。channel是進程內的通訊。

channel分為帶緩衝的以及不帶緩衝的。

ch:=make(chan int )建立一個不帶緩衝的channel。ch:=make(chan int,2,5)建立一個帶緩衝的channel,其中len(ch)是2,cap(ch)是5.

1.不帶緩衝的channel使用:

package main

import (
"fmt"
"time"
)

func main() {
ch := make(chan int)
go ff(ch)
fmt.Println("1", time.Now())
ch <- 2
fmt.Println("2", time.Now())
fmt.Println("main end")
fmt.Println("5", time.Now())
}

func ff(ch chan int) {
fmt.Println("3", time.Now())
time.Sleep(2 * time.Second)
<-ch
fmt.Println("ff end")
fmt.Println("4", time.Now())
}

輸出:

1 2016-05-12 12:50:02.4098584 +0800 CST
3 2016-05-12 12:50:02.4118585 +0800 CST
ff end
4 2016-05-12 12:50:04.4149731 +0800 CST
2 2016-05-12 12:50:04.4149731 +0800 CST
main end

5 2016-05-12 12:50:04.4149731 +0800 CST

根據時間可以分析一下程式的工作流程。首先main函數運行到ch<-2時候就阻塞了。不帶緩衝的channel接收資料後會阻塞,直到從這個channel中讀取資料後,阻塞的程式才恢複。等到ff函數運行到<-ch後,main函數才繼續運行。這是ff函數也在運行。從列印的時間可以看出兩個函數是並發的。


package main


import (
"fmt"
"time"
)


func main() {
ch := make(chan int)
go ff(ch)
fmt.Println("1", time.Now())
<-ch
fmt.Println("2", time.Now())
fmt.Println("main end")
fmt.Println("5", time.Now())
}


func ff(ch chan int) {
fmt.Println("3", time.Now())
time.Sleep(2 * time.Second)
ch <- 2
fmt.Println("ff end")
fmt.Println("4", time.Now())
}

輸出: 1 2016-05-12 13:03:00.3583545 +0800 CST
3 2016-05-12 13:03:00.3603546 +0800 CST
ff end
4 2016-05-12 13:03:02.3634692 +0800 CST
2 2016-05-12 13:03:02.3634692 +0800 CST
main end
5 2016-05-12 13:03:02.3634692 +0800 CST

根據列印的時間資訊可以分析,main函數在執行到<-ch時,阻塞。不帶緩衝的channel從中讀取資料時會阻塞,直到向其中寫入資料,阻塞的程式才會繼續執行。


2.帶緩衝的channel使用:

package main


import (
"fmt"
"time"
)


func main() {
ch := make(chan int, 2)
go ff(ch)
fmt.Println("1", time.Now())
ch <- 2
fmt.Println("2", time.Now())
fmt.Println("main end")
fmt.Println("5", time.Now())
}


func ff(ch chan int) {
fmt.Println("3", time.Now())
time.Sleep(2 * time.Second)
<-ch
fmt.Println("ff end")
fmt.Println("4", time.Now())
}

輸出:1 2016-05-12 13:07:27.0666093 +0800 CST
2 2016-05-12 13:07:27.0716096 +0800 CST
main end
5 2016-05-12 13:07:27.0716096 +0800 CST

根據列印資訊可以分析,main函數在執行到ch<-2的時候,沒有阻塞,而是繼續執行。那麼為什麼ff函數沒有來得及運行fmt.Println("3", time.Now())這條程式呢?

從上面不帶channel的程式可以看出,fmt.Println("3", time.Now())這句話啟動並執行時間比fmt.Println("1", time.Now())這句話啟動並執行時間要晚。晚多少時間和cpu有關。我們可以先不管。可以做出假設,ff函數裡面的fmt.Println("3", time.Now())還沒來得及執行,main函數就執行完了,程式就退出了。在這個過程中開的goroutine都不會執行,直接取消。

那麼,怎麼證明上面那段程式ff沒有執行是因為main結束了呢?可以在mian函數最後等待一小會。

修改上面的程式如下:

package main

import (
"fmt"
"time"
)

func main() {
ch := make(chan int, 2)
go ff(ch)
fmt.Println("1", time.Now())
ch <- 2
fmt.Println("2", time.Now())
fmt.Println("main end")
fmt.Println("5", time.Now())
time.Sleep(1 * time.Second)
}

func ff(ch chan int) {
fmt.Println("3", time.Now())
time.Sleep(2 * time.Second)
<-ch
fmt.Println("ff end")
fmt.Println("4", time.Now())
}

程式輸出:1 2016-05-12 13:17:44.0658997 +0800 CST
2 2016-05-12 13:17:44.0708999 +0800 CST
main end
5 2016-05-12 13:17:44.0708999 +0800 CST
3 2016-05-12 13:17:44.0678998 +0800 CST

可以看到,main最後等待了一秒時間,然後ff函數來得及執行fmt.Println("3", time.Now())。但是在ff函數執行time.Sleep(2 * time.Second)等待兩秒的時候,mian已經結束了。

更改一下channel讀取和寫入的順序,如下:

package main

import (
"fmt"
"time"
)

func main() {
ch := make(chan int, 2)
go ff(ch)
fmt.Println("1", time.Now())
<-ch
fmt.Println("2", time.Now())
fmt.Println("main end")
fmt.Println("5", time.Now())


}

func ff(ch chan int) {
fmt.Println("3", time.Now())
time.Sleep(2 * time.Second)
ch <- 2
fmt.Println("ff end")
fmt.Println("4", time.Now())
}

輸出:1 2016-05-12 13:20:06.0520208 +0800 CST
3 2016-05-12 13:20:06.055021 +0800 CST
ff end
4 2016-05-12 13:20:08.0571355 +0800 CST
2 2016-05-12 13:20:08.0571355 +0800 CST
main end
5 2016-05-12 13:20:08.0571355 +0800 CST

根據列印資訊可以分析,main函數在執行到<-ch這句話是阻塞,帶緩衝的channel如果裡面沒有資料,從中讀取的話會阻塞程式的運行。等到ff函數執行到ch <- 2時,main函數才從阻塞中恢複。

聯繫我們

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