func Test_TarsSelect(t *testing.T) {
trueCount := 0
falseCount := 0
for i := 0; i < 100000; i++ {
if TarsThread() {
trueCount++
} else {
falseCount++
}
}
fmt.Println("trueCount:", trueCount)
fmt.Println("falseCount:", falseCount)
}
func TarsThread() bool {
someChan := make(chan bool)
var gotChan bool
go SomeFunc(someChan)
select {
//10 毫秒超时
case <-time.After(10 * time.Millisecond):
case gotChan = <-someChan:
}
return gotChan
}
func SomeFunc(someChan chan bool) {
//休眠 10 微秒
time.Sleep(10 * time.Microsecond)
select {
case someChan <- true:
default:
}
}
如上所示的代码,在我这边执行 Test_TarsSelect
的结果是
=== RUN Test_TarsSelect
trueCount: 99961
falseCount: 39
一般情况下会认为应该全部为 true
。
如何解释这种现象呢? golang 中所有并发的程序的先后性都是不保证的吗?
我认为解决办法是 someChan 初始化时,可以修改为缓冲区长度为 1 。
另外一个同事认为是将 SomeFunc
中的 default 逻辑去掉,改成 case <- time.After(time.MillionSecond * 10)
。
二者都可以解决问题,你们推荐使用哪一种,或者有更合理的解决办法吗?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.