在写gobyexample的时候遇到一个问题如下
https://gobyexample.com/worker-pools
package main 2 import( 3 "fmt" 4 "time" 5 ) 6 type Message struct { 7 id int 8 data string 9 } 10 func main(){ 11 ch1:=make (chan Message ,19) 12 ch2:=make(chan Message ,19) 13 for i:=0;i<4;i++{ 14 go func (){ 15 f1(i,ch1,ch2) 16 }() 17 } 18 for i:=0;i<19;i++{ 19 var m Message 20 m.id=i 21 ch1<-m 22 } 23 for i:=0;i<19;i++{ 24 fmt.Println( <-ch2) 25 } 26 } 27 func f1(id int ,ch1 <-chan Message,ch2 chan <-Message){ 28 for msg :=range ch1{ 29 msg.data=fmt.Sprintf("%d",id) 30 time.Sleep(time.Second) 31 ch2<-msg 32 }
结果
{0 4} {1 4} {2 4} {3 4} {4 4} {5 4} {6 4} {7 4} {8 4} {9 4} {10 4} {11 4} {12 4} {13 4} {14 4} {15 4} {16 4} {17 4} {18 4}
按照道理说id应该是0,1,2,3怎么可能是4?
后来经过大牛指点做了一些改进
1 package main 2 import( 3 "fmt" 4 "time" 5 ) 6 type Message struct { 7 id int 8 data string 9 } 10 func main(){ 11 ch1:=make (chan Message ,19) 12 ch2:=make(chan Message ,19) 13 for i:=0;i<4;i++{ 14 go func (){ 15 f1(i,ch1,ch2) 16 }() 17 time.Sleep(time.Second) 18 } 19 for i:=0;i<19;i++{ 20 var m Message 21 m.id=i 22 ch1<-m 23 } 24 for i:=0;i<19;i++{ 25 fmt.Println( <-ch2) 26 } 27 } 28 func f1(id int ,ch1 <-chan Message,ch2 chan <-Message){ 29 for msg :=range ch1{ 30 msg.data=fmt.Sprintf("%d",id) 31 time.Sleep(time.Second) 32 ch2<-msg
在创建goroutine的时候多了一行time.Sleep(time.Second)
结果
{0 0} {1 1} {2 2} {3 3} {4 0} {5 1} {6 2} {7 3} {8 0} {9 1} {10 2} {11 3} {12 0} {13 1} {14 2} {15 3} {16 0} {17 1} {18 2}
相信大家都猜到为什么了吧:就是创建goroutine所花时间超过4次for循环当创建goroutine去取参数值的时候i已经为4了
但是真正出现这种情况的深层次原因,造成的是操作系统,还是语言本身,具体细节还望大牛指点
有疑问加站长微信联系(非本文作者)