草庐IT

golang fifo缓冲 channel

coder 2024-07-11 原文

根据我的理解:当 channel 已满时,GO 中的缓冲 channel 不是 FIFO。
我的应用程序需要这种行为(FIFO 行为)。
我怎样才能实现这种行为?是否有任何开源?
提前致谢

编辑:
有些人不喜欢这个问题,所以让我更清楚一点:
我的意思是当缓冲 channel 已满并且多个发件人被阻止时
在尝试将项目添加到 channel 时,它们的发布顺序
不是先进先出。您还可以阅读此讨论:https://github.com/golang/go/issues/11506

是的,我正在寻找实现该行为的第三方库。
抱歉没说清楚。

最佳答案

Go 中的缓冲 channel 始终是 FIFO。规范明确指出:

Channels act as first-in-first-out queues.

如果来自 channel 的值不是 FIFO,那么这是 channel 实现中的错误。

以下代码应始终以正确的顺序打印 1、2、3、4:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int, 3)
    ch <- 1
    ch <- 2
    ch <- 3

    go func() {
        ch <- 4
    }()

    time.Sleep(time.Second)

    for i := 0; i < 4; i++ {
        fmt.Println(<-ch)
    }
}

Playground link

请注意,当有多个并发发送者时,无法保证哪个值将首先发送。如果有多个等待发送者并且有人从 channel 缓冲区中删除一个元素(或者在无缓冲 channel 的情况下,尝试从 channel 接收),运行时将随机选择一个发送 goroutine。

例子:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int, 2)
    ch <- 1

    go func() {
        ch <- 2
    }()

    go func() {
        ch <- 3
    }()

    time.Sleep(time.Second)

    for i := 0; i < 3; i++ {
        fmt.Println(<-ch)
    }
}

Playground link

如果多次运行此代码,您会看到输出有时会是 1、2、3 或 1、3、2。(这在 playground 上不起作用,因为输出已缓存)

关于golang fifo缓冲 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37032559/

有关golang fifo缓冲 channel的更多相关文章

  1. Unity 血条及“掉血”缓冲效果 - 2

     视频教程:https://www.bilibili.com/video/BV1WJ411778C/?spm_id_from=333.999.0.0&vd_source=4a4c35da6aef7094d5990c213c39aa09使用素材(推荐使用GitZipforgithub下载):https://github.com/zheyuanzhou/Youtube-Unity-Tutorial/tree/master/EP45_Health%20Bar/Sprites效果如下图所示:首先在场景中创建一个新的Canvas,并命名为HeathBar,并创建三个Image作为前者的子物体,分别命名为

  2. ruby - 如何创建与帧缓冲区通信的 Ruby 应用程序? - 2

    我有一个RaspberryPiTFT7"触摸屏显示器,我想创建一个简单的应用程序来显示和输出系统数据(即CPU使用率、温度等)。我注意到目前常见的实现方法是使用pygame库输出到显示器连接到的帧缓冲区/dev/fb1。我想执行相同的操作,但使用Ruby,因为我更熟悉这门语言。有人可以为我指明正确的方向,让我知道如何开始吗?我查看了ruby​​game和gosu库,它们似乎能够做我想做的事情,即绘制屏幕,​​但我找不到任何关于如何将输出定向到的信息帧缓冲区本身。 最佳答案 rubycorelib有一个IO您应该能够使用该类将输出定向

  3. ruby-on-rails - 如何在 Rails Controller 中调用 channel 方法? - 2

    我有一个订阅用户的ActionCable方法。如果开始新的session,我也想为用户订阅新channel。我想不出在Controller中调用channel方法的正确语法。更新:问题是消息在发送时附加到聊天框,但是当发送第一条消息时,websocket连接尚未建立,因此在用户看来好像消息没有发送(因为它没有被附加)。channel/msgs_channel.rbclassMsgsChannel在我的convosController中,create方法,我尝试了几种方法:convos_controller.rbdefcreate@convo=Convo.create!({sender_

  4. ruby - 从 emacs 缓冲区运行 ruby - 2

    如何从缓冲区运行一段ruby​​代码,而不实际将缓冲区保存在文件中?一个场景是a)切换到暂存缓冲区b)M-xruby模式c)输入ruby代码d)“编译”缓冲区并在另一个缓冲区中打印结果。我不想将缓冲区内容保存在文件中,然后“编译”该文件2011年1月9日更新哪些是ruby​​-mode和inf-ruby的最新版本,我可以从哪里获得它们?我用的是ubuntunatty版的ruby模式和elpa版的emacs23.2的inf-ruby。在干净的emacs配置上,以下配置(见下文)失败:can'tconvertnilintoStringfrom(irb):1:in`eval'from(irb

  5. ruby-on-rails - 在 rails 插件之外无法访问 ActionCable channel - 2

    我正在尝试创建一个公开ActionCablechannel的gem,但我无法让它工作。这是我的宝贝#lib/my_channel.rbclassMyChannel然后我将gem添加到我的主要应用程序Gemfile,运行bundleinstall,启动控制台并运行MyChannel。没有屈服和错误,这意味着channel已正确包含。然后我将其添加到我的主应用程序//application.jsvarsocket="ws://localhost:3000/cable";varcable=ActionCable.createConsumer(socket);cable.subscriptio

  6. ruby - 了解 Ruby 和操作系统 I/O 缓冲 - 2

    IO缓冲在Ruby中是如何工作的?使用IO和File类时,数据刷新到底层流的频率如何?这与操作系统缓冲相比如何?在自信地读回数据进行处理之前,需要做什么来保证给定数据已写入磁盘? 最佳答案 RubyIO文档并未100%清楚地说明这种缓冲的工作原理,但您可以从文档中提取以下内容:RubyIO有自己的内部缓冲区除此之外,底层操作系统可能会或可能不会进一步缓冲数据。相关方法看:IO.flush:刷新IO。我还查看了Ruby源代码,对IO.flush的调用也调用了底层操作系统fflush().这应该足以让文件缓存,但不能保证物理数据到磁盘。

  7. javascript - 如何将两个输入 channel 连接到 ScriptProcessorNode? (网络音频 API,JavaScript) - 2

    我正在尝试实现一个具有两个输入channel和一个输出channel的ScriptProcessorNode。varsource=newArray(2);source[0]=context.createBufferSource();source[0].buffer=buffer[0];source[1]=context.createBufferSource();source[1].buffer=buffer[1];vartest=context.createScriptProcessor(4096,2,1);source[0].connect(test,0,0);source[1].c

  8. javascript - Node 子进程, channel 在 process.send 上关闭 - 2

    在我的工作文件中,我监听数据回调。someLib是Node串口。process.on('message',function(msg){someLib.on('data',function(data){console.log('somedata');process.send(data);});});这打印somedataError:channelclosed但是process.on('message',function(msg){process.send('foobar');});工作正常。这很奇怪,但有时第一个代码示例有效,所以channel关闭错误随机出现。来自http://node

  9. javascript - Node 编码和解码 utf-16 缓冲区 - 2

    我正在处理需要与C++tcp/udp套接字通信的javascript/nodejs应用程序。好像我从旧的C++客户端那里得到了一个utf16缓冲区。我现在没有找到将其转换为可读字符串的解决方案,而另一个方向似乎也是同样的问题。这两个方向有没有简单的方法?亲切的问候 最佳答案 如果您有一个UTF-16编码的缓冲区,您可以像这样将它转换为UTF-8字符串:letstring=buffer.toString('utf16le');要从流中读取这些,最简单的方法是在最后使用转换为字符串:letchunks=[];stream.on('dat

  10. javascript - 增加缓冲区的推荐方法? - 2

    假设我正在Node.js中构造一个可变长度的字符串或字节序列。buf.write的文档说:https://nodejs.org/api/buffer.html#buffer_buf_write_string_offset_length_encodingWritesstringtobufatoffsetaccordingtothecharacterencodinginencoding.Thelengthparameteristhenumberofbytestowrite.Ifbufdidnotcontainenoughspacetofittheentirestring,onlyapart

随机推荐