在写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了
但是真正出现这种情况的深层次原因,造成的是操作系统,还是语言本身,具体细节还望大牛指点