当前位置: 首页 > 面试题库 >

使用通道超时的golang

融泓
2023-03-14
问题内容

我正在使用goroutines /
channels检查网址列表是否可以访问。这是我的代码。这似乎总是返回true。为什么超时情况没有得到执行?目标是即使无法访问其中一个网址也要返回false

import "fmt"
import "time"

func check(u string) bool {
    time.Sleep(4 * time.Second)
    return true
}

func IsReachable(urls []string) bool {

    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            select {
            case ch <- check(u):
            case <-time.After(time.Second):
                ch<-false
            }
        }(url)
    }
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}

问题答案:

check(u)将在 当前的
goroutine(即正在运行的goroutine)中休眠func。该select语句仅在返回后才能正确运行,并且到那时,这两个分支都可以运行,并且运行时可以选择任何一个它。

您可以通过check在另一个goroutine中运行来解决该问题:

package main

import "fmt"
import "time"

func check(u string, checked chan<- bool) {
    time.Sleep(4 * time.Second)
    checked <- true
}

func IsReachable(urls []string) bool {

    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            checked := make(chan bool)
            go check(u, checked)
            select {
            case ret := <-checked:
                ch <- ret
            case <-time.After(1 * time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}

看来您想检查一组URL的可达性,如果其中一个可用,则返回true。如果超时时间比启动goroutine所需的时间长,则可以通过对所有URL设置一个超时来简化此过程。但是我们需要确保通道足够大以容纳所有检查的答案,否则那些不能“赢”的检查将永远被阻塞:

package main

import "fmt"
import "time"

func check(u string, ch chan<- bool) {
    time.Sleep(4 * time.Second)
    ch <- true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, len(urls))
    for _, url := range urls {
        go check(url, ch)
    }
    time.AfterFunc(time.Second, func() { ch <- false })
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1", "url2"}))
}


 类似资料:
  • 我是Grpc电话的新手。 目前,我正在使用Grpc。核心创建“通道”的新实例。请参阅下面的代码。 现在,我想在创建通道时添加一个连接超时。Grpc.Core有可能吗? 我知道可以在使用“Grpc.Net.Client.”时添加选项,但是,它只适用于. Net Core 2.1和我的项目不针对该框架。https://docs.microsoft.com/en-us/aspnet/core/grpc/

  • time 包中有一些有趣的功能可以和通道组合使用。 其中就包含了 time.Ticker 结构体,这个对象以指定的时间间隔重复的向通道 C 发送时间值: type Ticker struct { C <-chan Time // the channel on which the ticks are delivered. // contains filtered or unexpor

  • 问题内容: 我正在使用goroutines /频道。这是我的代码。为什么超时情况没有得到执行? 问题答案: 您的超时不会发生,因为您的goroutine 之一会每1.5秒(或大约1.5秒)重复发送一次值在您的频道上,并且只有在2秒钟内没有接收到任何值时才会发生超时。 一旦从接收到一个值,在下一次迭代中将再次执行一个 新的 调用,该调用将返回一个 新的 通道,在该通道上将仅在另外2秒钟后发送一个值。

  • 我正在使用Netty框架并实现客户端和服务器。我建立了多达1000个连接。我想在多个地方配置超时值。其中一些我能理解。下面是我的netty实现的netty行为: 1。许多异步连接都是从具有超时的客户端开始的(使用ChannelOption.CONNECT\u timeout\u MILLIS配置) 2。那些能够连接的客户端连接使用channelActive发送HTTP请求,并使用channelRe

  • 我正在尝试使用Django通道与浏览器建立websocket连接。websocket无法与服务器连接: 我使用命令运行服务器。 编辑:降级到16.2.0版。无济于事。

  • 问题内容: 我正在玩Golang,我创建了这个小应用程序,使用goroutines进行了多个并发的api调用。 当应用程序运行时,调用完成后,该应用程序将卡住,这是有道理的,因为由于通道未关闭,无法退出 范围c 循环。 我不确定在哪种情况下可以更好地关闭该通道。 问题答案: 当没有更多值要发送时,您将关闭通道,因此在这种情况下,所有goroutine已完成。 (请注意,from 仅将反映连接和协议