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 //優雅的讀取資料
需要注意的是:
帶緩衝區channe和不帶緩衝區channelpackage 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)
)}
不帶緩衝區示例:ch :=
make
(chan
int)
//不帶緩衝區
ch :=
make
(chan
int,10)
//帶緩衝區
channel實現作業池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和只寫channelpackage 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
}
一般定義唯讀和只寫的管道意義不大,更多時候我們可以在引數傳遞時候指明管道可讀還是可寫,即使當前管道是可讀寫的。
select-case實現非阻塞channelpackage main
import
("fmt"
"time"
)//只能向chan裡寫資料
func
send
(c chan
<-
int)
}//只能取channel中的資料
func
get(c <-
chan
int)
}func
main()
//結果01
2345
6789
原理通過select+case加入一組管道,當滿足(這裡說的滿足意思是有資料可讀或者可寫)select中的某個case時候,那麼該case返回,若都不滿足case,則走default分支。
channel頻率控制package main
import
("fmt"
)func
send
(c chan
int)
}func
main()
}//結果:get data : wd
在對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包 將可執...