当前位置: 首页 > 面试题库 >

使用for循环进行并发,匿名函数的行为异常

阎鸿煊
2023-03-14
问题内容

我已经找到了一种使代码按我希望的方式运行的方法,但是我想了解为什么它如此运行,以便提高对Go并发性的理解。

我正在测试sync.WaitGroup以等待一些goroutine完成,因为我计划以这种方式多次上传到Amazon S3。

这是我最初的代码:

func main() {

    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go func() {
            fmt.Println(i)
            time.Sleep(time.Second * 1)
            wg.Done()
        }()
    }

    wg.Wait()
}

我很惊讶地看到输出是:6, 6, 6, 6, 6

取而代之的是这样的:2, 4, 1, 5, 3

由于循环甚至没有达到6,这对我来说毫无意义。后来我将该i变量作为参数传递给匿名函数,然后按预期运行。

为什么会这样?我不明白


问题答案:

常见问题解答对此进行了介绍:以goroutines运行的闭包会发生什么?

在这种情况下,在for循环完成之前,不会对任何goroutine进行调度。为了使for循环中断,i不得小于或等于5,因此在该点为6。当goroutine运行时,它们各自打印i在闭包中捕获的单个变量的值。

当您将i参数作为html" target="_blank">参数传递给函数时,会将当前值复制到新变量中,并在该时刻捕获该值。



 类似资料:
  • 我想在一个并行外部循环中运行一个包含for循环(应该并行运行)的函数。因此看起来如下所示: 给定上面的代码,我希望在函数中为循环创建5个并行线程,并且希望这5个线程中的每个线程创建另一个线程来运行自己的并行for循环。

  • 我需要一个for循环中的click函数,这样每个id元素都可以单击。但是我还需要click函数中的I,这就是为什么我认为自动执行匿名函数是最好的方法。但出于某种原因,这不起作用,可能是因为单击函数不允许我转发参数?我做错了什么?

  • 我有一个python for循环,它执行一个bash脚本,如下所示(我将其简化为只包含需要显示的内容),我需要它在for循环中同时运行所有这些bash脚本,但要等到它们全部完成后才能继续串联。bash脚本是我唯一希望并行运行的部分。它是在同一for循环的下游做一些需要串联完成的事情。这可能吗? 以下是系列作品。没有脚本的并行执行,因为。如果我删除. etc(),它几乎立即出错,下游的任何东西都不再

  • 问题内容: 我听说Java 8提供了许多有关并发计算的实用程序。因此,我想知道并行化给定for循环的最简单方法是什么? 问题答案: 在流上阅读,它们都是新的流行。 特别注意并行性: “具有显式for循环的处理元素本质上是串行的。流通过将计算重新格式化为聚合操作的流水线,而不是作为对每个单独元素的命令性操作来促进并行执行。所有流操作都可以串行或并行执行。 ” 综上所述,没有并行的for循环,它们本质

  • 我听说Java8提供了很多关于并发计算的实用程序。因此,我想知道并行给定for循环的最简单方法是什么?