【问题标题】:Golang channel blocking operationsGolang 通道阻塞操作
【发布时间】:2021-11-28 18:27:32
【问题描述】:

我正在尝试停止子(或链接的)go 通道,但操作被阻塞(例如,具有等待网络连接的侦听器)

因为操作是阻塞的,所以for和case永远不会进入case

如何解决?

package main

import (
    "fmt"
    "time"
)

func main() {
    quit := make(chan bool)

    fmt.Println("Starting Channel 001")
    go func() {
        for {
            select {
            case <-quit:
                fmt.Println("Channel 001 stopped")
                // Expected result: hangFunction stop execution looping
                return
            default:
                hangFunction()
                time.Sleep(1 * time.Second)

            }
        }
    }()

    time.Sleep(2 * time.Second)

    fmt.Println("Closing channel 001")
    close(quit)

    time.Sleep(1 * time.Hour)
}

func hangFunction() {
    for {
        fmt.Println("[hangFunction] Looping")
        time.Sleep(1 * time.Second)
    }
}

【问题讨论】:

  • 您必须在hangFunction 内监控频道。
  • 通过关闭监听器来解锁网络操作。显示阻塞的实际代码会很有帮助。

标签: go channels


【解决方案1】:

您可以删除 hangFunction() 中永远阻塞的 for{} 循环:

func hangFunction() {
    fmt.Println("[hangFunction] Looping")
    time.Sleep(1 * time.Second)
}

或者您可以像 cmets 中提到的 @Adrian 那样在函数内监控频道,方法是:

func hangFunction(quit chan bool) {
    for {
        select {
        case <-quit:
            return
        default:
            fmt.Println("[hangFunction] Looping")
            time.Sleep(1 * time.Second)
        }
    }
}

这并不理想,因为您有两次相同的 select{} 块(在您的主程序和函数中)。它会起作用的。

【讨论】:

    猜你喜欢
    • 2015-04-22
    • 2017-12-08
    • 2017-04-21
    • 2016-07-06
    • 2017-06-07
    • 2021-08-24
    • 2021-05-03
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多