goroutine在使用channel同步和通信时,因为变量的共享访问特性,需要注意goroutine访问的变量是否被修改。
如下代码,看似合理,实际上因为i在main routine中已经被修改,会出现index越界访问异常。
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
const MAX = 3
cs := make([]chan string, MAX)
for i := 0; i < MAX; i++ {
fmt.Println("count i=", i)
cs[i] = make(chan string)
go func() {
for {
cs[i] <- "sender:" + strconv.Itoa(i)
time.Sleep(time.Millisecond * 500)
/fmt.Println(<-cs[i])
}
}()
}
go func() {
for {
select {
case msg1 := <-cs[0]:
fmt.Println(msg1)
case msg2 := <-cs[1]:
fmt.Println(msg2)
case msg3 := <-cs[2]:
fmt.Println(msg3)
case <-time.After(time.Second):
//fmt.Println("timeout reading ")
default:
//fmt.Println("No channel ready")
}
}
}()
fmt.Scanln()
}