- 知識點:
main主協程退出,其他協程全部退出
過去我們實現多線程通信通常通過共享內存來實現, 并需要對這塊內存區進行枷鎖操作, golang中我們可以通過channel實現協程通信
channel可以接受任何類型數據,并且類型安全
select多路復用:golang中用select關鍵字來檢索channel的IO事件,并支持多channel同時檢索,實現多路復用。select只接受IO操作,不接受表達式。
讀寫channel可以隱式轉換只讀只寫,反之不可以。
注意通道傳遞方式,引用類型。實驗轉換之后外部chan是否權限改變。
- 注意事項:以下
/*
注意事項:
chan,一定是一個協程寫,一個協程讀,若在一個協程里又寫又讀,肯定死鎖!因為在一個指令發生之后,會停止并等待
buffer chan 可以在一個協程里又寫又讀(有范圍)
不能使用 var ch chan int 的形式聲明,因為 nil chan無法receive也無法send
盡量不要在函數里面聲明chan,其他goroutine不好接收。
chan等待沒有回復,發生在其他goroutine會阻塞,不影響主程序。發生在主程,deadlock!
若為主程序設置開關,一定在其他goroutine不會被阻塞的地方寫入。
*/
package main
import (
. "fmt"
"strconv"
"time"
)
func main() {
go produce(ch5)
go consume(ch5)
time.Sleep(1*time.Second)
m2()
<- sw //主程序等待produce結束
}
//product
type product struct {
name string
attribute string
}
var ch1 = make(chan int)
var ch2 = make(chan int)
//var ch3 = make(chan int)
var ch5 = make(chan product)
//var ch5 = make(chan product,9) //此處,若ch5為buffer chan,會有何不同
var sw = make(chan bool)
//關于權限,隱式轉換,當外部讀寫chan作為實參傳入m1后,ch權限為receive-only,不可send。
//但是等m1返回之后,外部chan依然是receive-send。轉換時,權限只能往小,不能往大。
func produce(ch chan<- product){
println("produce")
for i := 0; i < 9; i++ {
ch <- product{"小浣熊",strconv.Itoa(i)}
println(i)
}
sw <- true // 阻塞作用
}
func consume(ch chan product) {
Println("consume")
for {
Println(<-ch)
}
}
//多路復用
func m2() {
select {
case i := <-ch1:
Println("ch1:",i)
case i := <-ch2:
Println("ch2:",i)
default:
Println("ch1 ch2 均無寫入")
}
}
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。