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

获取大量的大型缓冲通道块进行循环

锺离嘉容
2023-03-14
问题内容

我遇到了奇怪的行为。我正在使用缓冲通道,并且当使用大缓冲区时,整个程序的执行都会阻塞。在以下代码段中:

package main

import (
    "fmt"
)

func main() {
    choke := make(chan string, 150000)

    go func() {
        for i := 0; i < 10000000; i++ {
            choke <- string(i)
            fmt.Println("i=", i)
        }
    }()

    for {
        //fmt.Println(len(choke))
        if len(choke) >= 150000 {
            fmt.Println("Full")
        }
    }
}

我的程序阻塞了〜96000次迭代,并且从未达到“完全”打印,除非我len(choke)在评估之前将其打印出来。这可能是由于提供的延迟所致fmt.Println,因为也可以通过添加一个small来“解决”该问题time.Sleep

有人可以解释这种现象的原因吗?


问题答案:

发生这种情况是因为您的goroutine从未执行过。goroutine之外的“
for”循环是一个紧密的循环,没有任何阻塞操作,这意味着它将获得所有调度程序时间。因此,您创建的goroutine从未计划执行。

当您拥有print语句时,它会起作用,因为这是一个阻塞操作(I / O),可导致Go计划程序切换到您创建的goroutine。



 类似资料:
  • 问题内容: 我正在尝试创建一个异步通道,并且一直在查看http://golang.org/ref/spec#Making_slices_maps_and_channels。 缓冲区大小为10是什么意思?缓冲区大小具体代表/限制了什么? 问题答案: 缓冲区大小是在没有发送阻塞的情况下可以发送到通道的元素数。默认情况下,通道的缓冲区大小为0(可通过来获得此值)。这意味着每个发送都会阻塞,直到另一个go

  • 默认情况下,通道是不带缓冲区的。 发送端发送数据,同时必须又接收端相应的接收数据。 而带缓冲区的通道则允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。 不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。 package main imp

  • 我在张量流中使用keras创建了一个自定义模型。我使用的版本是tensorflow nightly 1.13.1。我使用官方工具构建了tensorfflow lite模型(方法tf.lite.TFLiteConverter.from_keras_model_file)。 创建模型后,我查看了输入形状,似乎没有什么不好。 tensorflow lite模型中的输入和输出形状为: 您可以注意到输入形状

  • 问题内容: 我知道Java和Perl都非常努力地在读取文件时找到一种适合所有默认缓冲区大小的大小,但是我发现他们的选择越来越过时,并且在更改默认选择时遇到问题Perl。 对于Perl,我认为默认情况下会使用8K缓冲区(类似于Java的选择),我无法使用perldoc网站搜索引擎(确实是Google)找到关于如何增加默认文件输入缓冲区大小的参考,例如, 64K。 通过上面的链接,显示8K缓冲区如何不

  • 主要内容:创建带缓冲通道,阻塞条件Go语言中有缓冲的通道(buffered channel)是一种在被接收前能存储一个或者多个值的通道。这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。通道会阻塞发送和接收动作的条件也会不同。只有在通道中没有要接收的值时,接收动作才会阻塞。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。 这导致有缓冲的通道和无缓冲的通道之间的一个很大的不同:无缓冲的通道保证进

  • Go语言中无缓冲的通道(unbuffered channel)是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。 如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。这种对通道进行发送和接收的交互行为本身就是同步的。其中任意一个操作都无法离开另一