【问题标题】:all go routines are asleep - deadlock所有 goroutine 都在休眠 - 死锁
【发布时间】:2015-12-29 21:43:14
【问题描述】:

我不明白为什么这段代码会出现死锁。我尝试了几种不同的方法来停止死锁(使用 WorkGroup 的几个不同版本)。这是我在 Go 的第一天,到目前为止,我对相当简单直接的操作的复杂性感到非常失望。我觉得我遗漏了一些大而明显的东西,但是我在这方面找到的所有文档似乎都与对我来说是一种非常基本的操作模式非常不同。所有文档都使用原始类型的通道(int、string)而不是更复杂的类型,所有这些都具有非常基本的 for 循环,或者它们位于频谱的另一端,其中函数是相当复杂的编排。

我想我真的是在寻找“这就是通常的做法”与 goroutines 的中间路径示例。

package main

import "fmt"

//import "sync"
import "time"

type Item struct {
    name string
}

type Truck struct {
    Cargo []Item
    name  string
}

func UnloadTrucks(c chan Truck) {

    for t := range c {
        fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name)
    }

}

func main() {
    trucks := make([]Truck, 2)

    ch := make(chan Truck)

    for i, _ := range trucks {

        trucks[i].name = fmt.Sprintf("Truck %d", i+1)

        fmt.Printf("Building %s\n", trucks[i].name)
    }

    for t := range trucks {
        go func(tr Truck) {

            itm := Item{}
            itm.name = "Groceries"

            fmt.Printf("Loading %s\n", tr.name)
            tr.Cargo = append(tr.Cargo, itm)
            ch <- tr

        }(trucks[t])
    }

    time.Sleep(50 * time.Millisecond)
    fmt.Println("Unloading Trucks")
    UnloadTrucks(ch)

    fmt.Println("Done")
}

【问题讨论】:

    标签: go goroutine


    【解决方案1】:

    你永远不会关闭“卡车”频道ch,所以UnloadTrucks永远不会回来。

    您可以在所有工作人员完成后关闭通道,使用 WaitGroup:

    go func() {
        wg.Wait()
        close(ch)
    }()
    UnloadTrucks(ch)
    

    http://play.golang.org/p/1V7UbYpsQr

    【讨论】:

      猜你喜欢
      • 2014-02-22
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 2018-05-28
      • 2012-09-06
      相关资源
      最近更新 更多