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

当没有通道可供读取时,怎么办?

汲灿
2023-03-14
问题内容

让我们以GoTour为例,它说明了我仅在有事件时才处理SDL事件的问题。

package main

import (
"fmt"
"time"
)

func main() {
tick := time.Tick(1e8)
boom := time.After(5e8)
for {
    select {
    case <-tick:
        fmt.Println("tick.")
    case <-boom:
        fmt.Println("BOOM!")
        return
    default:
        fmt.Println("    .")
        time.Sleep(5e7)
    }
}
}

这可行。但是,如果我不想在默认情况下打印或休眠,而只想继续循环怎么办?我尝试了这个:

    case <-boom:
        fmt.Println("BOOM!")
        return
    default: // Nothing here.
    }
}
}

但它阻止了。

我在这里和那里看到过有关goroutine调度的句子,但我不理解。所以我想我有两个问题:

1)为什么会阻塞?

2)如何使它不阻塞不执行任何操作?


问题答案:

您的原始示例产生了这个

    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
BOOM!

Wheraeas 您的第二个例子产生了这个

[process took too long]

不同之处在于您在此default案例中所做的。default案例总是可以运行,因此select带有默认语句的案例永远不会阻塞。第二个示例绕循环运行,不断选择准备运行的分支之一(大小写或默认)。您现在想知道为什么计时器永远不会触发。那是因为go例程没有被预先安排。因此,由于下面的循环永远不会执行任何IO,因此时间间隔永远不会触发。

for {
    select {
        // whatever
        default:
    }
}

有许多解决此问题的方法。首先,您可以像在第一个示例中那样放置一些IO。或者,您可以放置​​一个runtime.Gosched()。或者,您可以允许go运行时在runtime.GOMAXPROCS(2)中使用多个线程。

恕我直言,最好的方法是完全忽略默认语句,就像这样。没有默认语句的选择将阻塞,直到其中一个case语句准备就绪。如果要进行一些后台处理(您在默认语句中所做的处理),请启动goroutine-
这是可行的方法!

实际上,我在select语句中已经看到很多默认问题,所以我很想说永远不要使用它们。



 类似资料:
  • 我正在尝试从系统中读取。输入是这样的:第一个数字是测试用例的数量,然后是整数,然后是一些行。 问题是,尽管循环中存在条件,但当我完成最后一个测试时,while循环不会退出。

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

  • 我想运行node。js作为子流程,并向其提供输入。使用C,下面是我的一些示例代码。 我遇到的问题是,尽管子进程的stdout仍然指向终端,但在向子进程stdin输入打印的“helloworld”行后,我什么也看不到。即使我对管道进行了fflush()操作,我也看不到任何输出。但是,如果关闭管道的输入,则“Hello World”将显示在终端上。 子流程似乎只是缓冲-为什么?我希望最终将子流程std

  • 本文向大家介绍没有promise怎么办?相关面试题,主要包含被问及没有promise怎么办?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 没有promise,可以用回调函数代替

  • 问题内容: 我是Golang的新手。现在,我正在尝试找出如何在Golang中建立任意一对一频道的方法,其设置如下: 说我有两个goroutines numgen1和numgen2同时执行并将数字写入通道num1resp。num2。我想在新进程addnum中添加从numgen1和numgen2发送的数字。我已经尝试过这样的事情: 但这似乎令人遗憾。有人可以给我一些想法吗? 非常感谢您的帮助。 问题答

  • 假设我有一个简单的JFrame,它有一个包含3个面板的JTabbedPane,第二个面板包含一个JComponent。当“Tab2”面板从其容器中移除时,是否有方法通知JComponent?我的问题是JComponent可能在层次结构的深处。 显然,我在这里寻找的是SWING解决方案...:) 我试图使用setridorRemoved(),但没有成功。我显然做错了什么... ASCII艺术是用Ja