为了账号安全,请及时绑定邮箱和手机立即绑定

我使用 goroutine 进行 parral 的内存激增,最终 oom

我使用 goroutine 进行 parral 的内存激增,最终 oom

Go
料青山看我应如是 2022-05-18 15:31:53
我刚开始学围棋。我正在尝试进行总和计算。下面的代码func test() {    start := time.Now()    ret := make(chan int)    go foo(1, 100000, ret)    ssum := <- ret    elap := time.Since(start)    fmt.Println(ssum)    fmt.Printf("used time in milli is %d", elap)}func foo(start, end int, ret chan int) {    if start > end {        ret <- 0        return    }    if end - start <= 10000 {        sum := 0        for i := start; i <=end; i++ {            sum += i        }        ret <- sum        return    }    mid := (end - start) / 2    leftRet := make(chan int)    go foo(start, mid, leftRet)    leftNum := <- leftRet    rightRet := make(chan int)    go foo(mid+1, end, rightRet)    rightNum := <- rightRet    ret <- leftNum + rightNum}上面的代码做并行计算吗?由于 goroutine 不是多进程,甚至不是多线程。我不确定 goroutine 是否可以用来做 parrell 计算。为什么我会出现内存激增和 oom?
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

这不是并行执行任何操作。您创建一个 goroutine,然后立即等待它的返回值,每个 goroutine 执行计算,将结果写入通道并返回。所以那里没有并行性。如果在所有 goroutine 创建后将通道读取移动到该行,您可能会得到一些并发执行,因此两个 goroutine 可以运行。

您的程序不正确,这就是它没有终止的原因。mid不是(end-start)/2,是(end+start)/2。它很可能会陷入end-start大于 10000的情况,并且mid您最终会一遍又一遍地运行相同的开始值和结束值。在中间计算之后放置一个 println 语句,以查看起始值和结束值是什么。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信