Golang并发问题

Chr*_*ave 0 concurrency go

我正在学习Golang并发,并编写了一个程序来按顺序显示URL.我希望代码能够返回
http://bing.com * http://google.com*

但它总是返回http:/google.com***.好像变量被覆盖了.因为我正在使用goroutines,我希望它能在同一时间返回两个值.

func check(u string) string {
tmpres := u+"*****"
return tmpres
}

func IsReachable(url string) string {
ch := make(chan string, 1)
go func() { 

    ch <- check(url) 

     }()
select {
case reachable := <-ch:
    // use err and reply
    return reachable
case <-time.After(3* time.Second):
    // call timed out
    return "none"
}
   }



func main() {

var urls = []string{
  "http://bing.com/",
  "http://google.com/",
}

for _, url := range urls {
    go func() {
     fmt.Println(IsReachable(url)) 
     }()
}
time.Sleep(1 * time.Second)
  }
Run Code Online (Sandbox Code Playgroud)

Adr*_*ian 5

两个问题.首先,你创造了一个竞争条件.通过关闭循环变量,您将在运行循环的线程和运行goroutine的线程之间共享它,这会导致您描述的问题:当第一个URL启动的goroutine尝试运行时,该值变量的变化.您需要将其复制到局部变量,或将其作为参数传递,例如:

for _, url := range urls {
    go func(url string) {
     fmt.Println(IsReachable(url)) 
     }(url)
}
Run Code Online (Sandbox Code Playgroud)

其次,你说你想"按顺序"显示它们,这不是通常与并发/并行性兼容的目标,因为你无法控制并行操作的顺序.如果你想按顺序使用它们,你应该在一个线程中按顺序执行它们.否则,您必须收集结果,等待所有结果返回,然后在打印之前将结果排序回所需的顺序.