GO协程问题求助

mokeyWie
  • 2.4k

直接上代码

package main

import (
    "fmt"
    "strconv"
    "sync"
    "time"
)

type user struct {
    id   int
    name string
}

func main() {
    users := make([]user, 5)
    for i := 0; i < 5; i++ {
        users[i] = user{i, "name" + strconv.Itoa(i)}
    }
    wg := &sync.WaitGroup{}
    wg.Add(10)
    // 传递user指针协程里打印出来的是同一user
    for _, u := range users {
        go handleUserPointer(&u, wg)
    }
    time.Sleep(time.Second)
    // 传递值正常
    for _, u := range users {
        go handleUserValue(u, wg)
    }
    wg.Wait()
}

// 指针传递
func handleUserPointer(user *user, wg *sync.WaitGroup) {
    fmt.Println(user)
    time.Sleep(time.Millisecond * 200)
    wg.Done()
}

// 值传递
func handleUserValue(user user, wg *sync.WaitGroup) {
    fmt.Println(user)
    time.Sleep(time.Millisecond * 200)
    wg.Done()
}

输出结果

&{4 name4}
&{4 name4}
&{4 name4}
&{4 name4}
&{4 name4}
{0 name0}
{1 name1}
{4 name4}
{3 name3}
{2 name2}

for range里面启协程处理,传递user指针总是同一个,请问这是什么原因?

回复
阅读 1.2k
5 个回答

哈,我也是了解了一下才知道..

u一直是u,但指向的值不停地在变化。

go routine启动太慢啦,要是多加个延时,还发现不了呢...

for _, u := range users {
   go handleUserPointer(&u, wg)
   time.Sleep(time.Second)
}

因为goroutine启动时间长,指针早就直到最后一个了。

咱们就不谈什么协程协程问题, 我就说一句, 你在协程中使用指针不加锁, 还循环执行, 这合理吗?

for range 根本就没有坑, 是用的人不加锁.

for range 循环的时候获取 keyvalue 的指指针是不明智的,这两个变量会在循环开始就初始化了,每次循环之后修改其值,获取指针永远都会是同一个

你知道吗?

宣传栏