What goes wrong when embedding goroutines inside a for loop?

148 views
Skip to first unread message

Zhaoxun Yan

unread,
Feb 17, 2022, 11:45:39 AM2/17/22
to golang-nuts
package main
import "fmt"

func main() {
    targetIndice := make([]int, 3)
    targetIndice[0] = 5
    targetIndice[2] = 4
   
    for i,n := range targetIndice{
        fmt.Printf("%d : %d \n", i, n)
    }
   
    c := make(chan int)
    for i, n:= range targetIndice{
        go func(){
            fmt.Printf("targetIndice[%d]=%d \n", i, n)
            c <- 1
        }()
    }
   
    for i:=0; i<3; i++{
        <- c
    }
   
}

-----go run main.go---------
0 : 5
1 : 0
2 : 4
targetIndice[2]=4
targetIndice[2]=4
targetIndice[2]=4

jake...@gmail.com

unread,
Feb 17, 2022, 12:31:42 PM2/17/22
to golang-nuts
I think this explains it pretty well: Common Mistakes: Using goroutines on loop iterator variables

Ian Davis

unread,
Feb 17, 2022, 12:33:00 PM2/17/22
to golan...@googlegroups.com

Try passing i and n to the closure as arguments. See https://go.dev/play/p/qzPgDWiE4Og for example




Jan Mercl

unread,
Feb 17, 2022, 12:33:38 PM2/17/22
to Zhaoxun Yan, golang-nuts
On Thu, Feb 17, 2022 at 5:44 PM Zhaoxun Yan <yan.z...@gmail.com> wrote:

This goes wrong:

        jnml@3900x:~/tmp$ cat main.go

        package main
       
        import "fmt"
       
        func main() {
                targetIndice := make([]int, 3)
                targetIndice[0] = 5
                targetIndice[2] = 4
       
                for i, n := range targetIndice {
                        fmt.Printf("%d : %d \n", i, n)
                }
       
                c := make(chan int)
                for i, n := range targetIndice {
                        go func() {
                                fmt.Printf("targetIndice[%d]=%d \n", i, n)
                                c <- 1
                        }()
                }
       
                for i := 0; i < 3; i++ {
                        <-c
                }
        }
        jnml@3900x:~/tmp$ go run -race main.go

        0 : 5
        1 : 0
        2 : 4
        ==================
        WARNING: DATA RACE
        Read at 0x00c0000e4018 by goroutine 7:
          main.main.func1()
              /home/jnml/tmp/main.go:17 +0x57
       
        Previous write at 0x00c0000e4018 by main goroutine:
          main.main()
              /home/jnml/tmp/main.go:15 +0x1d4
       
        Goroutine 7 (running) created at:
          main.main()
              /home/jnml/tmp/main.go:16 +0x18f
        ==================
        ==================
        targetIndice[2]=4
        WARNING: DATA RACE
        Read at 0x00c0000e4028 by goroutine 8:
          main.main.func1()
              /home/jnml/tmp/main.go:17 +0x73
       
        targetIndice[2]=4
        Previous write at 0x00c0000e4028 by main goroutine:
          main.main()
              /home/jnml/tmp/main.go:15 +0x1f1
       
        Goroutine 8 (running) created at:
          main.main()
              /home/jnml/tmp/main.go:16 +0x18f
        ==================
        targetIndice[2]=4
        Found 2 data race(s)
        exit status 66
        jnml@3900x:~/tmp$


Reply all
Reply to author
Forward
0 new messages