为什么在这个 golang 代码片段中,指向 WaitGroup 的指针的地址是不同的?

huangapple go评论88阅读模式
英文:

Why are addresses of pointers to a WaitGroup different in this golang snippet?

问题

playground上的代码片段中,我正在打印sync.WaitGroup的指针地址,它们都是不同的。为什么会这样?

func Run() *sync.WaitGroup {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Printf("goroutine %p\n", &wg)

        time.Sleep(5 * time.Second)
        fmt.Println("wokeup")
    }()

    fmt.Printf("returning %p\n", &wg)
    return &wg
}

func main() {
    runtime.GOMAXPROCS(3)
    wg := Run()

    fmt.Printf("     main %p\n", &wg)
    wg.Wait()
}

典型的输出显示,在函数Runmain内部的地址是不同的。我希望它们是相同的,难道不是吗?

returning 0xc0840045c0
     main 0xc084000038
goroutine 0xc0840045c0
wokeup
英文:

Code snippet on playground

I am printing the pointer address for sync.WaitGroup and they are all different. Why?

func Run() *sync.WaitGroup {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Printf("goroutine %p\n", &wg)

        time.Sleep(5 * time.Second)
        fmt.Println("wokeup")
    }()

    fmt.Printf("returning %p\n", &wg)
    return &wg
}

func main() {
    runtime.GOMAXPROCS(3)
    wg := Run()

    fmt.Printf("     main %p\n", &wg)
    wg.Wait()
}

Typical output shows that the address is diff between that inside the function Run and main. I'd expect that to be the same, n'est-ce pas ?

returning 0xc0840045c0
     main 0xc084000038
goroutine 0xc0840045c0
wokeup

答案1

得分: 1

好的,以下是翻译好的内容:

嗯,如果你注意到,"returning"的打印语句和"goroutine"的打印语句给出了相同的地址。你的"main"打印是有问题的。看看这一行代码:

fmt.Printf("     main %p\n", &wg)

你注意到了什么?你打印的是&wg,也就是wg被赋值的地址。

现在看看你的Run()函数的返回值,你返回的是&wg,也就是wg作为变量的第一个声明的指针。

所以基本上你的"main"打印是打印了wg指针地址的地址,而不是指针地址本身...希望这样说得清楚...

但是,是的,将"main"中的那一行代码改为

fmt.Printf("     main %p\n", wg)

应该可以解决问题。

英文:

Well, if you notice, the "returning" print statement and the "goroutine" print statement give the same address. Your "main" print is what is off. Look at the line:

fmt.Printf("     main %p\n", &wg)

What do you notice? You're printing &wg, the address of whatever wg is assigned to.

Now look at the return value of your Run() function, you're returning &wg. A pointer to your first declaration of wg as a variable.

So basically your "main" print is printing the the address of the wg pointer address rather than the pointer address itself... hope that makes sense...

But yeah, changing the line in "main" to

fmt.Printf("     main %p\n", wg)

should work.

答案2

得分: 1

例如,

package main

import "fmt"
import "sync"
import "time"
import "runtime"

func Run() *sync.WaitGroup {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Printf("goroutine %p\n", &wg)
        fmt.Println("sleep for 5s")
        time.Sleep(5 * time.Second)
        fmt.Println("wokeup")
    }()
    fmt.Printf("returning %p\n", &wg)
    return &wg
}

func main() {
    runtime.GOMAXPROCS(3)
    wg := Run()
    fmt.Printf("     main %p\n", wg)
    wg.Wait()
}

输出:

returning 0x1052e2c0
     main 0x1052e2c0
goroutine 0x1052e2c0
sleep for 5s

fmt.Printf("     main %p\n", &wg)

改为

fmt.Printf("     main %p\n", wg)

main函数中,变量wg包含了你想要的地址。你正在打印包含地址的变量的地址。

英文:

For example,

package main

import "fmt"
import "sync"
import "time"
import "runtime"

func Run() *sync.WaitGroup {
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		fmt.Printf("goroutine %p\n", &wg)
		fmt.Println("sleep for 5s")
		time.Sleep(5 * time.Second)
		fmt.Println("wokeup")
	}()
	fmt.Printf("returning %p\n", &wg)
	return &wg
}

func main() {
	runtime.GOMAXPROCS(3)
	wg := Run()
	fmt.Printf("     main %p\n", wg)
	wg.Wait()
}

Output:

returning 0x1052e2c0
     main 0x1052e2c0
goroutine 0x1052e2c0
sleep for 5s

Change

fmt.Printf("     main %p\n", &wg)

to

fmt.Printf("     main %p\n", wg)

In main, the variable wg contains the address you want. You are printing the address of the variable that contains the address.

huangapple
  • 本文由 发表于 2014年4月8日 13:52:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/22928581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定