GO协程问题求助

发布于 2022-09-11 21:03:30 字数 1094 浏览 18 评论 0

直接上代码

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指针总是同一个,请问这是什么原因?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白云悠悠 2022-09-18 21:03:30

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

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

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

for _, u := range users {
   go handleUserPointer(&u, wg)
   time.Sleep(time.Second)
}
谁把谁当真 2022-09-18 21:03:30

找到原因了,参考:https://juejin.im/post/5c5415...

ˇ宁静的妩媚 2022-09-18 21:03:30

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

享受孤独 2022-09-18 21:03:30

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

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

安稳善良 2022-09-18 21:03:30

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文