Go語言學習 channel

2021-09-25 05:57:40 字數 4000 閱讀 5203

channel俗稱管道,用於資料傳遞或資料共享,其本質是乙個先進先出的佇列,使用goroutine+channel進行資料通訊簡單高效,同時也執行緒安全,多個goroutine可同時修改乙個channel,不需要加鎖。

channel可分為三種型別:

channel使用

定義和宣告

var readonlychan <-

chan

int// 唯讀chan

var writeonlychan chan

<-

int// 只寫chan

var mychan chan

int//讀寫channel

//定義完成以後需要make來分配記憶體空間,不然使用會deadlock

mychannel =

make

(chan

int,10)

//或者

read_only :=

make

(<-

chan

int,10)

//定義唯讀的channel

write_only :=

make

(chan

<-

int,10)

//定義只寫的channel

read_write :=

make

(chan

int,10)

//可同時讀寫

讀寫資料

需要注意的是:

ch <-

"wd"

//寫資料

a :=

<- ch //讀取資料

a, ok :=

<-ch //優雅的讀取資料

迴圈管道

需要注意的是:

package main

import

("fmt"

"time"

)func

main()

close

(mychannel)

//關閉管道

fmt.

println

("data lenght: "

,len

(mychannel)

)for v :=

range mychannel

fmt.

printf

("data lenght: %d"

,len

(mychannel)

)}

帶緩衝區channe和不帶緩衝區channel

ch :=

make

(chan

int)

//不帶緩衝區

ch :=

make

(chan

int,10)

//帶緩衝區

不帶緩衝區示例:

package main

import

"fmt"

func

test

(c chan

int)

}func

main()

}//結果:

send 0

send 1

get 0

get 1

send 2

send 3

get 2

get 3

send 4

send 5

get 4

get 5

send 6

send 7

get 6

get 7

send 8

send 9

get 8

get 9

channel實現作業池

我們建立三個channel,乙個channel用於接受任務,乙個channel用於保持結果,還有乙個channel用於決定程式退出的時候。

package main

import

("fmt"

)func

task

(taskch, resch chan

int, exitch chan

bool)}

()for t :=

range taskch

exitch <-

true

//處理完傳送退出訊號

}func

main()

close

(taskch)}(

)for i :=

0; i <

5; i++

gofunc()

close

(resch)

//任務處理完成關閉結果管道,不然range報錯

close

(exitch)

//關閉退出管道}(

)for res :=

range resch

}

唯讀channel和只寫channel

一般定義唯讀和只寫的管道意義不大,更多時候我們可以在引數傳遞時候指明管道可讀還是可寫,即使當前管道是可讀寫的。

package main

import

("fmt"

"time"

)//只能向chan裡寫資料

func

send

(c chan

<-

int)

}//只能取channel中的資料

func

get(c <-

chan

int)

}func

main()

//結果01

2345

6789

select-case實現非阻塞channel

原理通過select+case加入一組管道,當滿足(這裡說的滿足意思是有資料可讀或者可寫)select中的某個case時候,那麼該case返回,若都不滿足case,則走default分支。

package main

import

("fmt"

)func

send

(c chan

int)

}func

main()

}//結果:get data : wd

channel頻率控制

在對channel進行讀寫的時,go還提供了非常人性化的操作,那就是對讀寫的頻率控制,通過time.ticker實現。

示例:

package main

import

("time"

"fmt"

)func

main()

close

(requests)

limiter := time.

tick

(time.second*1)

for req:=

range requests

}//結果:

requets 1

2018-07

-0610:

17:35.98056403

+0800 cst m=

+1.004248763

requets 2

2018-07

-0610:

17:36.978123472

+0800 cst m=

+2.001798205

requets 3

2018-07

-0610:

17:37.980869517

+0800 cst m=

+3.004544250

requets 4

2018-07

-0610:

17:38.976868836

+0800 cst m=

+4.000533569

Go語言學習日誌之channel引發死鎖問題

今天在看到go中的channel時,就自己動手試了一下這個資料結構,先貼原始 package main import fmt time func main 乍一看沒毛病,但就是這麼簡單的乙個測試執行就直接報錯了 fatal error all goroutines are asleep deadlo...

GO語言學習

sudo apt get install golang但是用ubuntu的庫安裝有幾個不好的地方 因此建議不要使用ubuntu的庫安裝golang環境 golang社群的安裝指導 wget tar c usr local zxf go1.6.2.linux amd64.tar.gz設定環境變數,修改...

Go語言學習

執行 go run go main函式 打包 go build 用於測試編譯包,在專案目錄下生成可執行檔案 有main包 go install 主要用來生成庫和工具。一是編譯包檔案 無main包 將編譯後的包檔案放到 pkg 目錄下 gopath pkg 二是編譯生成可執行檔案 有main包 將可執...