go - 从 channel 读取时未检测到 "deadlock"

标签 go deadlock channel

在复杂程序中,从 channel 读取不确定数量任务的执行结果时,出现未检测到的死锁,如何处理?网络服务器?

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UTC().UnixNano())

    results := make(chan int, 100)

    // we can't know how many tasks there will be
    for i := 0; i < rand.Intn(1<<8)+1<<8; i++ {
        go func(i int) {
            time.Sleep(time.Second)
            results <- i
        }(i)
    }

    // can't close channel here 
    // because it is still written in
    //close(results)

    // something else is going on other threads (think web server)
    // therefore a deadlock won't be detected
    go func() {
        for {
            time.Sleep(time.Second)
        }
    }()

    for j := range results {
        fmt.Println(j)
        // we just stuck in here
    }
}

如果程序更简单,请转到 detects a deadlock and properly fails .大多数示例要么获取已知数量的结果,要么按顺序写入 channel 。

最佳答案

诀窍是使用 sync.WaitGroup 并以非阻塞方式等待任务完成。

var wg sync.WaitGroup

// we can't know how many tasks there will be
for i := 0; i < rand.Intn(1<<8)+1<<8; i++ {
    wg.Add(1)
    go func(i int) {
        time.Sleep(time.Second)
        results <- i
        wg.Done()
    }(i)
}

// wait for all tasks to finish in other thread
go func() {
    wg.Wait()
    close(results)
}()

// execution continues here so you can print results

另请参阅:Go Concurrency Patterns: Pipelines and cancellation - The Go Blog

关于go - 从 channel 读取时未检测到 "deadlock",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38319358/

相关文章:

image - 无法在 GOLANG 中解码不同的图像格式(分配计数不匹配)

go - 类型声明中的匿名字段?

java网络接受线程之间的网络连接

golang所有goroutines都睡着了 - 死锁

facebook - 如何为 Facebook SDK 创建 “channel.html” 文件

Go routine 不接收通过 channel 发送的所有数据——玩具示例程序

go - GO语言中slice,channel,map的赋值和直接赋值有什么区别

go - net/http调用的全局控制列表

mysql - Sonar 库 4.5.4 : MySQL deadlock

使用多线程代码在一张表上出现 MySQL 死锁