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

Golang - 如何将多个渠道链接在一起?

Golang - 如何将多个渠道链接在一起?

Go
绝地无双 2023-03-15 14:55:42
尝试安排项目,将项目发送到“状态”通道以获取状态,然后将项目发送到“删除”通道以删除项目。我正在设置两个通道的大小,预计在项目删除完成后我会“完成”。在“完成”之前执行“删除”之后,代码似乎正在停止。为什么我会收到“致命错误:所有 goroutines 都睡着了 - 死锁!” 在“删除项目”之后和“完成”之前?哪个例程正在睡觉?https://go.dev/play/p/W49niF5xngQpackage mainimport (    "fmt"    "time")func main() {    numbers := []int{1, 2, 4}    for _, n := range numbers {        fmt.Printf("Schedule and delete %d items.\n", n)        statusChan := make(chan string, n)        deleteChan := make(chan string, n)        done := make(chan bool)        go func(n int, statusChan chan<- string) {            for i := 0; i < n; i++ {                i := i                go func(n int, statusChan chan<- string) {                    fmt.Printf("Scheduling item number ... %d\n", i)                    itemNum := fmt.Sprintf("item_num_%d\n", i)                    time.Sleep(500 * time.Millisecond)                    statusChan <- itemNum                }(n, statusChan)            }        }(n, statusChan)        go func(statusChan <-chan string, deleteChan chan<- string) {            for itemNum := range statusChan {                fmt.Printf("Checking status of item number ... %s\n", itemNum)                time.Sleep(500 * time.Millisecond)                deleteChan <- itemNum            }        }(statusChan, deleteChan)        go func(deleteChan <-chan string, done chan<- bool) {            for itemNum := range deleteChan {                fmt.Printf("Delete item: %s", itemNum)                time.Sleep(500 * time.Millisecond)            }            fmt.Printf("Done with scheduling and deleting %d item.\n", n)            done <- true        }(deleteChan, done)        <-done    }}
查看完整描述

1 回答

?
达令说

TA贡献1821条经验 获得超6个赞

这似乎符合您的想法。我使用“***”作为“全部完成”的信号。


package main

import (

    "fmt"

    "time"

)


func main() {

    numbers := []int{1, 2, 4}

    for _, n := range numbers {

        fmt.Printf("Schedule and delete %d items.\n", n)

        statusChan := make(chan string, n)

        deleteChan := make(chan string, n)

        done := make(chan bool)


        go func(n int, statusChan chan<- string) {

            for i := 0; i < n; i++ {

                fmt.Printf("Scheduling item number ... %d\n", i)

                itemNum := fmt.Sprintf("item_num_%d\n", i)

                time.Sleep(500 * time.Millisecond)

                statusChan <- itemNum

            }

            statusChan <- "***"

        }(n, statusChan)


        go func(statusChan <-chan string, deleteChan chan<- string) {

            for itemNum := range statusChan {

              fmt.Printf("Checking status of item number ... %s\n", itemNum)

              deleteChan <- itemNum

            }

        }(statusChan, deleteChan)


        go func(deleteChan <-chan string, done chan<- bool) {

            for itemNum := range deleteChan {

              if itemNum == "***" {

                break

              }

              fmt.Printf("Delete item: %s", itemNum)

            }

            fmt.Printf("Done with scheduling and deleting %d item.\n", n)

            done <- true

        }(deleteChan, done)

        <-done

    }

}


查看完整回答
反对 回复 2023-03-15
  • 1 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号