简体   繁体   中英

Should I pass request object to goroutine in blocking for-select loop coming from channel?

I have the following for-select structure in code:

go func(runCh chan Caller, shutdownSignal chan bool) {
        for {
            select {
            case request := <-runCh:
                go func() {
                    w.Run(&request)
                }()
            case <-shutdownSignal:
                w.Shutdown()
                return
            }
        }
    }(runCh, shutdownCh)

Will I have some problems with this part:

case request := <-runCh:
    go func() {
        w.Run(&request)
    }()

?

If yes, then why?

In other words - does Using goroutines on loop iterator variables part of Common Mistakes also apply to my case and why it does/does not apply here?

No ( does not apply here ), you have new variable (memory address) on each loop iteration:

 case request := <-runCh:

Because this := creates new variable distinct from previous one, proof:

package main

import (
    "fmt"
    "time"
)

func main() {
    runCh := make(chan int, 2)
    runCh <- 1
    runCh <- 2
    for i := 1; i <= 2; i++ {
        select {
        case request := <-runCh:
            go func() {
                fmt.Println(request, &request)
                time.Sleep(200 * time.Millisecond)
                fmt.Println(request, &request)

            }()
        }
    }
    time.Sleep(500 * time.Millisecond)

}

Output (the address of request in each loop iteration is different):

1 0xc0000b8000
2 0xc0000b8008
1 0xc0000b8000
2 0xc0000b8008

See: 0xc0000b8000 != 0xc0000b8008

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM