某網站的面試題:
鏈接:http://www.coder55.com/article/34958
首先執行了一下,確實死鎖,如圖:
按題目要求添加代碼:
第一次執行:
第二次:
第三次:
第六次:
因爲線程執行順序並不一定,所以加上答案中的方法,並不一定得到相應的結果。
當然題目要求的是不報錯,但是如果寫入c2的線程執行晚於讀取線程是否還是會報錯?
第二次執行已經證明晚於main線程。
改造後的代碼:
package main
import (
"fmt"
"runtime"
"time"
)
var c1 = make(chan int)
var c2 = make(chan int)
func main() {
//設置cpu核數爲1
runtime.GOMAXPROCS(1)
//讓當前線程讓出 cpu 以讓其它線程運行,它不會掛起當前線程,因此當前線程未來會繼續執行
runtime.Gosched()
go func(){
c2<-1
}()
go func() {
fmt.Println("1111111")
c1 <-<- c2
}()
go func() {
runtime.Gosched()
c1 <-<- c2
fmt.Println("2222222")
}()
<- c1
time.Sleep(3 * time.Second)
}
可以保證輸出結果永遠是"1111111" "2222222"
runtime:
runtime
調度器是個非常有用的東西,關於 runtime
包幾個方法:
-
Gosched:讓當前線程讓出
cpu
以讓其它線程運行,它不會掛起當前線程,因此當前線程未來會繼續執行 -
NumCPU:返回當前系統的
CPU
核數量 -
GOMAXPROCS:設置最大的可同時使用的
CPU
核數 -
Goexit:退出當前
goroutine
(但是defer
語句會照常執行) -
NumGoroutine:返回正在執行和排隊的任務總數
-
GOOS:目標操作系統
@轉載,鏈接https://studygolang.com/articles/13994?fr=sidebar
剛開始看到符號"<-<-",百度了一下,查到的都是"chan <-"或者"<- chan",查了好久。直到看了這篇博客:
原文鏈接:https://blog.csdn.net/weixin_42663840/article/details/81285886
意思就是將chan中的數據讀取出來,放到了另一個chan中。省略了中間變量的寫法。
文中還有一點:
查了一下:
官方的go編譯器限制channel最多能容納到65535個元素,儘管如此,我們也不應該傳遞體積過大的元素值,因爲channel的數據從進入到流出會涉及到數據拷貝操作。如果元素體積過大,最好的方法還是使用傳遞指針來取代傳遞值。
channel類型是可以帶有方向的,假設T是一種類型
chan T是雙向channel類型,編譯器允許對雙向channel同時進行發送和接收。
chan<- T是隻寫channel類型,編譯器只允許往channel裏面發送數據。
<-chan T是隻讀channel類型,編輯器只允許從channel裏面接收數據。
雙向類型的channel,可以被強制轉換成只讀channel或者是隻寫channel,但是反過來卻不行,只讀和只寫channel是不可以轉換成雙向channel的。
@原文鏈接:https://www.jianshu.com/p/5046bf8593c3
單向channel一般用於方法的入參或返回值。