Golang goroutine同步预期行为

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

golang goroutine synchronization expected behaviour

问题

以下是代码的翻译:

下面的代码尝试在主goroutine上发送到通道,并从另一个goroutine接收,但有时会按预期返回,有时会在不打印任何内容的情况下退出。

package main

import "fmt"

func main() {
    ch := make(chan bool)

    go func() {
        data := <-ch
        fmt.Printf("Received: %t", data)
    }()
    ch <- true
}

同时,下面的代码每次都按预期工作,一个区别是添加了额外的检查以检查通道是否关闭,这总是产生相同的预期输出。这是否确保对通道的检查是必需的而不是可选的?或者代码有什么问题?

package main

import "fmt"

func main() {
    ch := make(chan bool)

    go func() {
        data, ok := <-ch
        if !ok {
            fmt.Println("Channel closed")
            return
        }
        fmt.Printf("Received: %t", data)
    }()
    ch <- true
}
英文:

The following piece of code try to send to the channel on the main goroutine and receive from another goroutine but a few times it returns as expected but a few times it exits without printing any on the console screen

package main

import &quot;fmt&quot;

func main() {
	ch := make(chan bool)

	go func() {
		data := &lt;-ch
		fmt.Printf(&quot;Received: %t&quot;, data)
	}()
	ch &lt;- true
}

At the same time, the following piece of code works as expected everytime, one difference is that an additional check has been added to check if the channel is closed or not which always throws the same expected output.
Does this ensure that a check on the channel is a must than optional ? or anything wrong with the code

package main

import &quot;fmt&quot;

func main() {
	ch := make(chan bool)

	go func() {
		data, ok := &lt;-ch
		if !ok {
			fmt.Println(&quot;Channel closed&quot;)
			return
		}
		fmt.Printf(&quot;Received: %t&quot;, data)
	}()
	ch &lt;- true
}

答案1

得分: 1

你应该在主例程退出之前等待 goroutine 完成。

package main

import (
	"fmt"
	"sync"
)

func main() {
	ch := make(chan bool)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		data := <-ch
		fmt.Printf("接收到数据:%t", data)
	}()
	ch <- true
	wg.Wait()
}

在这段代码中,我们使用了 sync.WaitGroup 来等待 goroutine 完成。在主例程中,我们创建了一个 chan bool 类型的通道 ch,然后使用 wg.Add(1) 将等待组的计数器加一。接下来,我们启动了一个匿名的 goroutine,它会从通道 ch 中接收数据,并打印出接收到的数据。在 goroutine 的最后,我们使用 defer wg.Done() 来通知等待组计数器减一。然后,我们将 true 发送到通道 ch 中。最后,我们使用 wg.Wait() 来等待等待组中的计数器归零,确保 goroutine 完成后再退出主例程。

英文:

You should wait for goroutine to complete before main routine exit.

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
)

func main() {
	ch := make(chan bool)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		data := &lt;-ch
		fmt.Printf(&quot;Received: %t&quot;, data)
	}()
	ch &lt;- true
	wg.Wait()
}

答案2

得分: -1

问题的翻译如下:

问题是你的第二段代码并不总是打印出"Received: true"。我进行了多次测试。

正如@jub0bs所提到的,不能保证你的goroutine在主程序之前完成。你必须自己进行控制。

英文:

The thing is your second piece of code doesn't print Received: true every time. I tested it several times.

As @jub0bs mentioned there is no guarantee that your goroutine finishes before the main routine. You must control it yourself.

huangapple
  • 本文由 发表于 2022年2月6日 16:37:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/71005471.html
匿名

发表评论

匿名网友

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

确定