這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
在寫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了
但是真正出現這種情況的深層次原因,造成的是作業系統,還是語言本身,具體細節還望大牛指點