【问题标题】:Calling multiple functions with different signatures concurrently同时调用具有不同签名的多个函数
【发布时间】:2021-01-27 16:27:48
【问题描述】:

我想要一些关于我正在尝试构建的实现细节的反馈。我想要实现的是具有可以同时调用的具有不同签名的多个函数。

按顺序调用协程中的函数可以正常工作,但我想知道是否有办法以更惯用的方式执行此操作,例如迭代一片函数。

由于每个函数都有不同的参数和返回值,我很难弄清楚最好的方法是什么。可以在这里看到一个与我的目标有点相似的示例:Golang - How do you create a slice of functions with different signatures?,但那里的代码只是调用函数并且不考虑任何返回值。

我的想法可能吗?

【问题讨论】:

  • 如果你有返回值,你必须单独处理每个函数调用。这听起来很像过度概括。有一些语言是为此而生的,Go 不是其中之一。您可以手动并行化不同的功能。无需将它们放在一个切片中并对其进行迭代。
  • 哦...绝对不要使用reflect
  • 查看我的回答,了解如何同时运行具有不同签名和返回值的函数:stackoverflow.com/questions/65563745/…

标签: go


【解决方案1】:

您可以使用来自linked question 的代码,只需将v.Call(params) 包装到在其自己的goroutine 中执行的匿名函数中,如下所示:

...
// WaitGroup to wait on goroutines to finish their execution
var wg sync.WaitGroup
    
for a, v := range f {
    v := reflect.TypeOf(v)
    //calling the function from reflect
    val := reflect.ValueOf(f[a])
    params := make([]reflect.Value, v.NumIn())
    if v.NumIn() == 1 {
        params[0] = reflect.ValueOf(1564)
    } else if v.NumIn() == 2 {
        params[0] = reflect.ValueOf("Test FROM reflect")
        params[1] = reflect.ValueOf(float32(123456))
    }

    // Run them in parallel
    wg.Add(1)
    go func() {
        defer wg.Done()
        val.Call(params)
    }()
}
wg.Wait()

查看Go Playground

至于返回值 Value.Call() 返回 []Value 这是返回值的一部分 - 所以你也在这里。您的问题没有指定您打算如何处理结果,但鉴于它们将并行生成,您可能需要通过通道发送它们 - 您也可以在匿名函数中执行此操作(在处理返回切片之后) .

【讨论】:

    【解决方案2】:

    go func() { MyPackage.MyFunc(with, whatsoever, signature); }() - 大致来说,这就是你所需要的。您跨越的 goroutine(使用 go 关键字)与并发函数的数量一样多。

    goroutine 没有“返回值”的概念。为此,您必须使用channels。它们是主要的通信机制。因此,您使用任意签名的某个函数 f 生成一个新的 goroutine,当它完成并获得一些结果时,您将它发送到某个频道在 goroutine 之间共享以进行通信

    通道是线程安全的,并且经过精心设计,可以优雅地处理此类通信。作为编程语言,Go 提供了很少的关键字来处理对通道的读/写。因此,Go 中的(并发)编程非常基础。

    但是,当然,您可以以不同的方式处理它。共享一些受某种锁定保护的可变内存,或者依赖于无锁compareAndSet 时尚。可以说,这是不那么惯用的方式,通常必须避免。总是喜欢频道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 2011-11-11
      • 2016-05-10
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多