- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一个函数 IsAPrimaryColour(),它通过调用其他三个函数 IsRed()、IsGreen() 和 来工作>IsBlue()。由于这三个功能彼此相当独立,因此它们可以同时运行。返回条件为:
我正在努力解决的问题是,如果其他三个函数返回 true,如何退出该函数,而且如果它们都返回 false,则如何等待所有三个函数完成。如果我使用sync.WaitGroup对象,我需要等待所有3个go例程完成才能从调用函数返回。
因此,我使用循环计数器来跟踪我在 channel 上收到消息的次数,并在收到所有 3 条消息后启动程序。
https://play.golang.org/p/kNfqWVq4Wix
package main
import (
"errors"
"fmt"
"time"
)
func main() {
x := "something"
result, err := IsAPrimaryColour(x)
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf("Result: %v\n", result)
}
}
func IsAPrimaryColour(value interface{}) (bool, error) {
found := make(chan bool, 3)
errors := make(chan error, 3)
defer close(found)
defer close(errors)
var nsec int64 = time.Now().UnixNano()
//call the first function, return the result on the 'found' channel and any errors on the 'errors' channel
go func() {
result, err := IsRed(value)
if err != nil {
errors <- err
} else {
found <- result
}
fmt.Printf("IsRed done in %f nanoseconds \n", float64(time.Now().UnixNano()-nsec))
}()
//call the second function, return the result on the 'found' channel and any errors on the 'errors' channel
go func() {
result, err := IsGreen(value)
if err != nil {
errors <- err
} else {
found <- result
}
fmt.Printf("IsGreen done in %f nanoseconds \n", float64(time.Now().UnixNano()-nsec))
}()
//call the third function, return the result on the 'found' channel and any errors on the 'errors' channel
go func() {
result, err := IsBlue(value)
if err != nil {
errors <- err
} else {
found <- result
}
fmt.Printf("IsBlue done in %f nanoseconds \n", float64(time.Now().UnixNano()-nsec))
}()
//loop counter which will be incremented every time we read a value from the 'found' channel
var counter int
for {
select {
case result := <-found:
counter++
fmt.Printf("received a value on the results channel after %f nanoseconds. Value of counter is %d\n", float64(time.Now().UnixNano()-nsec), counter)
if result {
fmt.Printf("some goroutine returned true\n")
return true, nil
}
case err := <-errors:
if err != nil {
fmt.Printf("some goroutine returned an error\n")
return false, err
}
default:
}
//check if we have received all 3 messages on the 'found' channel. If so, all 3 functions must have returned false and we can thus return false also
if counter == 3 {
fmt.Printf("all goroutines have finished and none of them returned true\n")
return false, nil
}
}
}
func IsRed(value interface{}) (bool, error) {
return false, nil
}
func IsGreen(value interface{}) (bool, error) {
time.Sleep(time.Millisecond * 100) //change this to a value greater than 200 to make this function take longer than IsBlue()
return true, nil
}
func IsBlue(value interface{}) (bool, error) {
time.Sleep(time.Millisecond * 200)
return false, errors.New("something went wrong")
}
虽然这工作得很好,但我想知道我是否没有忽略一些语言功能以更好的方式做到这一点?
最佳答案
errgroup.WithContext
可以帮助简化这里的并发性。
如果发生错误或找到结果,您希望停止所有 goroutine。如果您可以将“找到结果”表示为可区分的错误(类似于 io.EOF 的行),那么您可以使用 errgroup 的内置“取消”在第一个错误时”行为关闭整个组:
func IsAPrimaryColour(ctx context.Context, value interface{}) (bool, error) {
var nsec int64 = time.Now().UnixNano()
errFound := errors.New("result found")
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
result, err := IsRed(ctx, value)
if result {
err = errFound
}
fmt.Printf("IsRed done in %f nanoseconds \n", float64(time.Now().UnixNano()-nsec))
return err
})
…
err := g.Wait()
if err == errFound {
fmt.Printf("some goroutine returned errFound\n")
return true, nil
}
if err != nil {
fmt.Printf("some goroutine returned an error\n")
return false, err
}
fmt.Printf("all goroutines have finished and none of them returned true\n")
return false, nil
}
关于go - 检查所有 goroutine 是否已完成而不使用 wg.Wait(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68939352/
var wg sync.WaitGroup var v int32 = 0 for i = 0; i < 100; i++{ go func(){ wg.Add(1) // wro
1。我触发了一个 goroutine(运行第三方程序),我正在使用 wg.Wait() 等待它完成 2。在 wg.Wait() 之前,我想为用户提供一个选项来取消正在运行的第三方程序(如果他愿意的话)
假设我有一个函数 IsAPrimaryColour(),它通过调用其他三个函数 IsRed()、IsGreen() 和 来工作>IsBlue()。由于这三个功能彼此相当独立,因此它们可以同时运行。返回
假设我有一个函数 IsAPrimaryColour(),它通过调用其他三个函数 IsRed()、IsGreen() 和 来工作>IsBlue()。由于这三个功能彼此相当独立,因此它们可以同时运行。返回
我在使用 defer wg.Done 和 channel 时遇到问题。 如果我像下面这样编码,就没有问题。 for i := 0; i < ntasks; i++ { wg.Add(1)
我有一个要抓取的网址列表。我想做的是将所有成功抓取的页面数据存储到一个 channel 中,当我完成后,将其转储到一个 slice 中。我不知道我会得到多少成功的抓取,所以我不能指定一个固定的长度。我
我正在使用 PIC-IoT WG wifi 开发板开展一个项目。我正在尝试修改演示代码以便能够在我自己的服务器上使用它。该演示在多个地方使用了这样的代码: #include static void
我有一个示例代码(您可以在 Go Playground 上找到它): package main import ( "fmt" "sync" "time" ) func main
关闭。 这个问题不符合 Stack Overflow guidelines 。它目前不接受答案。 这个问题似乎与 a specific programming problem, a software
所有在 Debian 9+ 上运行都没有问题,使用相同的设置和安装方法。 当我尝试启动服务时 systemctl start wg-quick@wg0 它在日志中显示错误: wg-quick[9290
我目前正在开发一个用 java 实现的已安装桌面应用程序。我打算将 Google Calendar API 集成到应用程序中。 在授权过程中,我来到了这个阶段,我只能通过触发显示用户同意页面的浏览器来
我是一名优秀的程序员,十分优秀!