dongna1593 2018-12-13 12:41
浏览 84
已采纳

为什么即使关闭通道并且所有工作人员都退出后,我的代码中还是存在死锁?

Here is my code:

package main

import (
    "fmt"
    "sync"
)

func worker(id int, wg sync.WaitGroup, work <-chan int) {
    defer func() {
    wg.Done()
    fmt.Println("worker", id, "done")
    }()

    fmt.Println("worker", id, "started")

    for w := range work {
        fmt.Println("worker", id, "got work", w)
    }
}

func main() {

    work := make(chan int, 2)
    var wg sync.WaitGroup

    for i := 0; i < 3; i++ {
    wg.Add(1)
        go worker(i, wg, work)
    }

    // Generate work and send.
    for i := 0; i < 5; i++ {
        work <- i
    }

    close(work)

    fmt.Println("waiting ...")
    wg.Wait()
    fmt.Println("done")
}

Here is the output:

worker 2 started
worker 2 got work 0
worker 2 got work 1
worker 2 got work 2
worker 1 started
waiting ...
worker 0 started
worker 0 done
worker 1 got work 4
worker 1 done
worker 2 got work 3
worker 2 done
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001409c)
        /usr/local/Cellar/go/1.10.2/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420014090)
        /usr/local/Cellar/go/1.10.2/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
        /Users/lone/bar/bar.go:39 +0x15f
exit status 2

Why did this deadlock occur?

  • 写回答

1条回答 默认 最新

  • dtkl55257 2018-12-13 12:48
    关注

    From the docs:

    A WaitGroup must not be copied after first use.

    Try to pass a pointer to your worker function instead:

    func worker(id int, wg *sync.WaitGroup, work <-chan int)
    

    Here's the complete code: Playground

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改