一文引發的延續思考
package main
import (
"fmt"
)func main()
}()fmt.println("the val:", <-ch)
}func getval(i int) int
無論 select 最終選擇了哪個 case,getval() 都會按照原始碼順序執行:getval(1) 和 getval(2),也就是它們必然先輸出:
getval, i= 1
getval, i= 2
package main
import (
"fmt"
"time"
)func talk(msg string, sleep int) <-chan string
}()return ch
}func fanin(input1, input2 <-chan string) <-chan string
} }()
return ch
}func main()
}
每次進入以下 select 語句時:
select
<-input1
和<-input2
都會執行,相應的值是:a x 和 b x(其中 x 是 0-5)。但每次 select 只會選擇其中乙個 case 執行,所以<-input1
和<-input2
的結果,必然有乙個被丟棄了,也就是不會被寫入 ch 中。因此,一共只會輸出 5 次,另外 5 次結果丟掉了。(你會發現,輸出的 5 次結果中,x 比如是 0 1 2 3 4)
而 main 中迴圈 10 次,只獲得 5 次結果,所以輸出 5 次後,報死鎖。
如果改為這樣就一切正常:
select
我的理解:
case ch <- <-input:
語句是分成兩段執行的,可以理解為
t := <- input //case選擇還未明確的時候會執行
ch <- t //如果沒有選擇此case,則不執行此語句
並且這是兩條語句,具有先後順序
所以<-input 執行後,沒有選擇此case,<-input的結果就會被丟棄掉,從而導致上述的死鎖問題。
上述提到
無論 select 最終選擇了哪個 case,getval() 都會按照原始碼順序執行:getval(1) 和 getval(2),也就是它們必然先輸出:
getval, i= 1
getval, i= 2
思考一:如果getval()方法執行的時間不同,select的執行時長是取決於執行時間長的,還是時間的總和?
func getval1(i int) int
func getval2(i int) int
func main()
fmt.println(time.since(begintime))
} }()
time.sleep(time.second * 10)
}
輸出的結果
getval, i= 1
getval, i= 2
3.0015862s
getval, i= 1
getval, i= 2
3.0021938s
getval, i= 1
getval, i= 2
3.0019246s
可以看出來,每次select都會按順序執行case語句,並且select的執行時間為case語句的總和
當然在實際生產中也不會有這種寫法
正確的寫法:
func main() ()
go func() ()
go func()
} }()
for i := 0; i < 2; i++
fmt.println(time.since(begin))
}
輸出結果,此時取決於執行時間最長的getval()
getval, i= 1
1getval, i= 2
22.0020979s
在實際生產中,select語句只用於接受channel中的數值,而不是去執行某一方法
細心的小夥伴已經發現了,上述的寫法有兩個bug
新起協程中,因為for語句導致一直空轉,該協程不會被銷毀
如果ch被close以後,對其傳送資料,會導致panic
加點注釋看看輸出的結果
func main() ()
go func() ()
time.sleep(2 * time.second)
fmt.println("goroutine num", runtime.numgoroutine())
go func()
}()for
} }()
for i := 0; i < 2; i++
close(ch)
fmt.println(time.since(begin))
fmt.println("goroutine num", runtime.numgoroutine())
ch2 <- 1
time.sleep(time.second * 1)
}
輸出的結果
getval, i= 1
getval, i= 2
goroutine num 212
2.0020965s
goroutine num 2
panic err send on closed channel
可以看到,for迴圈的協程並沒有被釋放,並且在後續的ch <-
操作中也報出了panic異常 syslog 引發死鎖
主線程在寫 syslog,同時在訊號處理函式中也在寫syslog,當主線程在寫的時候,如果同時觸發了訊號,那麼將會導致死鎖。pstack 4289 0 0x00000036768df9ee in lll lock wait private from lib64 libc.so.6 1 0x00000...
停課引發的思考
快一周沒去機房了,好懷念在在學習的日子,以至於經常夢到自己在設計程式。唉,說到底還是自己太貪玩,沒有珍惜這來之不易的學習環境。當10期大部分人因遲到被禁止進的時候,我們幾個在大大咧咧的學習,甚至連週末兩天都沒有做到按時上課。結果,讓公尺老師動怒,被判了個無期徒刑。失去了才知道珍惜,也好,這樣再次得到...
電梯引發的思考
有了孩子之後,精力確實有限。珍惜現在的所有的所謂的悠閒時光吧。之前在婦幼醫院看過電梯,上面寫著 層層都停,單層停靠,雙層停靠,1 8層停靠,醫院人多滿載後就不開門了。還有我們經常見的高層電梯,低層電梯。我就想閒下來的時候寫個電梯控制的小程式。彌補一下空虛的心靈。夜深人靜的晚上我就在想,如果讓我寫我會...