go 例程未从通道收集所有对象

2023-12-26

我有一个go-routine将对象添加到通道中,然后我有 4 个go-routines处理通道对象。处理只不过是将对象添加到数组中。但有时,最终数组中会丢失对象。所以我假设在某个时刻通道停止收集对象。我有以下代码:

package main

import (
    "log"
    "sync"
)

func main() {
    j := 0
    for {
        if j == 10 {
            break
        }
        wg := sync.WaitGroup{}
        months := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"}
        hits := make(chan string)
        i := 0
        wg.Add(1)
        go func() {
            defer close(hits)
            for {
                if i == 25 {
                    wg.Done()
                    return
                }
                for _, month := range months {
                    hits <- month
                }
                i++
            }
        }()

        temp := []string{}
        for updateWorker := 1; updateWorker <= 4; updateWorker++ {
            wg.Add(1)
            go func() {
                for hit := range hits {
                    temp = append(temp, hit)
                }
                wg.Done()
                return
            }()
        }

        wg.Wait()

        log.Printf("length of temp %+v\n", len(temp))
        j++
    }
}

我在用sync库来同步例程。我将相同的过程循环 10 次以测试输出是否一致。我期待这样的输出:

length of temp 175

它是 175,因为我发送了 7 个月的字符串 25 次。 但有时输出小于175,不知道为什么。我对 Go 例程有点初学者。那么有人可以帮我找到原因吗?谢谢。


问题是updateWorkergoroutine 都从以下位置收集结果hits通道(到目前为止一切顺利),并且它们都将结果存储到temp局部变数不同步。这是不行的。

从多个 goroutine(其中至少有一个是写入)对所有变量的访问必须同步。

如果您在启用竞争检测器的情况下运行它,它会尖叫着数据竞争(go run -race app.go).

如果减少数量,它会立即产生有效结果updateWorkergoroutine 设为 1,因为这样我们就消除了应用程序的单一数据竞争源:

for updateWorker := 1; updateWorker <= 1; updateWorker++ {
    // ...
}

如果你想保留多个updateWorkergoroutine,它们对共享的访问temp变量必须同步。

With a sync.Mutex https://golang.org/pkg/sync/#Mutex:

var (
    mu   sync.Mutex
    temp []string
)
for updateWorker := 1; updateWorker <= 4; updateWorker++ {
    wg.Add(1)
    go func() {
        for hit := range hits {
            mu.Lock()
            temp = append(temp, hit)
            mu.Unlock()
        }
        wg.Done()
        return
    }()
}

另请注意,在这个简单的示例中,使用多个updateWorker对于 goroutine,添加上述同步(锁定)甚至会使其性能低于仅使用其中之一的性能。

为了正确分配工作和收集结果,请查看以下答案:这是 Go 中惯用的工作线程池吗? https://stackoverflow.com/questions/38170852/is-this-an-idiomatic-worker-thread-pool-in-go/38172204#38172204

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go 例程未从通道收集所有对象 的相关文章

  • Java 执行器和长寿命线程

    我继承了一些使用 Executors newFixedThreadPool 4 的代码运行 4 个长寿命线程来完成应用程序的所有工作 这是推荐的吗 我读过Java 并发实践 https rads stackoverflow com amzn
  • 鸭子在 Go 中打字

    我想写一个Join函数接受任意对象String 方法 package main import fmt strings type myint int func i myint String string return fmt Sprintf
  • 断点会停止所有线程吗?

    如果我的程序中有两个线程同时运行 并在其中一个线程上设置了断点 那么当遇到此断点时 另一个线程也会停止 还是会继续执行 我用 Java 编写并使用 NetBeans 断点可以选择它们的行为方式 挂起单个线程或所有线程
  • Golang GAE - 小胡子结构中的 intID

    这是一个Example https www dropbox com sh ur2ws1jnik6euef PjVJSwDTUc Blog Golang zip该应用程序的 关键代码在 golang code handler handler
  • 解组转义 XML

    在 Go 中 我将如何解码此 XML 响应 我尝试过建立一个自定义UnMarshal方法在我的Answerstruct 但我运气不太好
  • 打印到 stdout 会导致阻塞的 goroutine 运行吗?

    作为一个愚蠢的基本线程练习 我一直在尝试实现理发师睡觉的问题 http en wikipedia org wiki Sleeping barber problem在戈兰 对于通道来说 这应该很容易 但我遇到了一个 heisenbug 也就是
  • GoLang ssh:尽管将其设置为 nil,但仍出现“必须指定 HosKeyCallback”错误

    我正在尝试使用 GoLang 连接到远程服务器 在客户端配置中 除了用户和密码之外 我将 HostKeyCallback 设置为 nil 以便它接受每个主机 config ssh ClientConfig User user HostKey
  • 正确的文件扩展名或缩写是什么。 golang 的文本/模板?

    我正在考虑为其创建语法荧光笔 但我不知道这种特定类型模板的常规缩写 In 例子之一 http golang org pkg text template example Template helpers从文本 模板 godoc 中 它们引用
  • 使用 Akka 1.3 的 actor 时,我需要注意生产者-消费者速率匹配吗?

    使用 Akka 1 3 时 我是否需要担心当生成消息的 Actor 生成消息的速度比使用消息的 Actor 的处理速度快时会发生什么 如果没有任何机制 在长时间运行的进程中 队列大小将增大以消耗所有可用内存 The doc http doc
  • 关于java中的生产者和消费者模式与阻塞队列方法

    我正在研究有关java中线程的生产者和消费者设计模式 最近我在java 5中进行了探索 并介绍了Java 5中BlockingQueue数据结构的介绍 现在它变得更简单了 因为BlockingQueue通过引入阻塞方法隐式地提供了这种控制p
  • 使用连接池后如何处理过多的并发连接?

    Scenario 假设您有一个拥有大量流量的网站或应用程序 即使使用数据库连接池 性能也会受到真正的打击 站点 应用程序甚至可能崩溃 因为并发连接太多 Question 人们有什么选择来处理这个问题 我的想法 我在想有这个问题的人可以创建多
  • 在 Java EE 中手动启动新线程安全吗?

    对于在会话范围内的 JSF 托管 bean 中生成线程是否安全 我找不到明确的答案 线程需要调用无状态 EJB 实例 依赖注入到托管 bean 上的方法 背景是我们有一份需要很长时间才能生成的报告 由于我们无法更改服务器设置 这导致 HTT
  • 如何关闭 gorm 1.20.0 中的数据库实例

    由于我没有在 Close 函数中找到 gorm 实例 任何帮助将不胜感激 dbURI fmt Sprintf user s password s dbname s port s sslmode s TimeZone s username p
  • 在 Go 中,如何将结构体转换为字节数组?

    我有一个我定义的结构实例 我想将其转换为字节数组 我尝试了 byte my struct 但这不起作用 另外 我还被指出二进制包 http golang org pkg encoding binary 但我不确定我应该使用哪个函数以及应该如
  • Condition 接口中的 signalAll 与对象中的 notificationAll

    1 昨天我才问过这个问题条件与等待通知机制 https stackoverflow com questions 10395571 condition vs wait notify mechanism 2 我想编辑相同的内容并在我的问题中添加
  • RSA OAEP、Golang 加密、Java 解密 -BadPaddingException:解密错误

    我正在尝试解密使用 RSA OAEP 在 Golang 中加密的字符串 但出现 BadPaddingException 解密错误 很难弄清楚我错过了什么 这是Golang加密方法 func encryptString rootPEM io
  • select 语句是否保证通道选择的顺序?

    继从这个答案 https stackoverflow com a 25795236 274460 如果一个 goroutine 在两个通道上进行选择 是否保证通道的选择顺序与其发送的顺序相同 我对发送者是单线程的情况特别感兴趣 例如 是否保
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • 使用GCD实现并发读独占写模型

    我试图了解使用 Grand Central Dispatch GCD 实现控制资源访问的并发读独占写模型的正确方法 假设有一个 NSMutableDictionary 被大量读取并且偶尔更新 确保读取始终与字典状态一致的正确方法是什么 当然
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs

随机推荐

  • nvd3.js:无法将 onClick 事件与 svg 中的数据点绑定

    我试图将数据点与 onclick 事件绑定 以便我可以显示一个带有一些附加详细信息和链接的覆盖框 我正在使用 nv point类来访问数据点 问题是我无法将 onclick 事件注册到这些数据点 这是代码 d3 selectAll nv p
  • Cassandra .csv 导入错误:批量太大

    我正在尝试通过复制命令将数据从 csv 文件导入到 Cassandra 3 2 1 文件中只有 299 行 14 列 我收到错误 无法导入 299 行 InvalidRequest code 2200 无效查询 message 批次太大 我
  • 使用 javascript 更快地选择元素

    我想知道是否有更快的方法来选择它 document getElementById container getElementsByTagName p 0 getElementsByTagName strong 1 innerText 结构是
  • 从基类方法克隆派生类

    我有一个抽象基类Base它具有一些共同的属性 以及许多实现不同逻辑但很少有附加字段的派生属性 public abstract Base protected int field1 protected int field2 protected
  • 获取 x86-64 指令的大小

    我需要一个可以计算 x86 64 指令长度的函数 例如 它可以像这样使用 char ret 0xc3 size t length instructionLength ret length在此示例中将设置为 1 我不想包含整个反汇编库 因为我
  • 编译静态库与标准库的链接(静态)

    我正在尝试编译一个静态库 我们称之为library a 该库消耗标准库的资源 该库可以通过某种方式静态链接标准库 我已经证明了类似的事情 g c library static libstdc o library o ar rcs libra
  • 如何观察目录的变化? [复制]

    这个问题在这里已经有答案了 在 python 核心中找不到任何东西来执行此操作 谁能推荐一个库或 电池 来做到这一点 理想情况下 我希望它是可移植的 但如果它仅适用于 Unix 我的服务器 也没关系 在 Linux 上 您可能对 pyino
  • Reflection.Emit 与 CodeDOM

    使用 Reflection Emit 库与 CodeDOM 在运行时动态生成代码有哪些优缺点 我正在尝试根据运行时以 XML 形式提供的元数据在系统中生成一些 相对复杂的 动态类 我将生成扩展应用程序程序集中现有类的类 实现附加接口 添加方
  • 矢量绘图中的微光动画

    我一直在尝试使用动画矢量可绘制图标实现闪烁动画 我正在寻找的效果与此类似 我已经用过Facebook 微光库 https facebook github io shimmer android 为了获得这种效果 尽管这正是我所需要的 但我想使
  • Typescript Array[T] 接受 {..T} 作为有效类型

    使用时这咬了我useState
  • 检索 Sitecore 项目在内容树中的位置 A 以及位置 B 中的用户

    给定以下内容树 我如何将经销商与汽车关联起来 以便获得这样的 URL http website Dealerships JimWhite 福特 http website Dealerships JimWhite Ford 我需要能够在汽车下
  • 有没有办法在 Kotlin 中使用初始化函数构造 HashSet?

    从文件中读取星星2016 年 Facebook 黑客杯 https www facebook com hackercup problem 910374079035613 Boomerang Constellations问题 可以定义以下扩展
  • 如何调用同步谷歌日历

    首先阅读以下问题 从 Android 上的日历提供程序中删除事件 https stackoverflow com questions 18774394 delete events from calendar provider on andr
  • Eclipse 无法识别字符串和类

    我保存了一个由 eclipse 构建的项目 然后我的电脑就死机了 当我修复它并重新格式化时 我重新下载了 eclipse 等 实际上 当我按下 eclipse exe 时 它会显示 eclipse juno 图标 但窗口的名称是 Java
  • C++“内存屏障”示例[重复]

    这个问题在这里已经有答案了 我正在阅读有关 volatile 关键字的问题的答案 https stackoverflow com a 2485177 997112 https stackoverflow com a 2485177 9971
  • C# 中任意等级数组的索引

    我需要迭代任意排名的数组 这是为了阅读和写作 所以GetEnumerator不管用 Array SetValue object int 不适用于多维数组 Array SetValue object params int 需要过多的算术来迭代
  • 在 git bash 中创建一个新文件

    我已经运行了 Windows 版 Git 但我不确定它是否应该充当文本编辑器 我想我是用 Vim 编辑器安装的 但是在 Git Bash shell 中如何创建文件 例如网页 html git add webpage html 返回为 fa
  • Flutter:如何在手势检测器中禁用 onTap 一段时间?

    我有一个GestureDetector在自定义无状态视图中 什么时候onTap触发后 我显示了一个显示一些信息的小吃店 当用户快速多次单击时 它会永远显示小吃栏 源代码 https github com ammaratef45 zold f
  • Ivy,主配置是什么,为什么它不拉动jvyaml?

    我有以下常春藤文件
  • go 例程未从通道收集所有对象

    我有一个go routine将对象添加到通道中 然后我有 4 个go routines处理通道对象 处理只不过是将对象添加到数组中 但有时 最终数组中会丢失对象 所以我假设在某个时刻通道停止收集对象 我有以下代码 package main