草庐IT

multithreading - 在 Go 中关闭自馈 channel

coder 2024-07-09 原文

我正在尝试使用 Go 中的并发和 channel 。我面临的问题主要是并发的想法,所以我不认为以下逻辑是错误的或者应该改变。

我有一个缓冲区大小为“N”的缓冲 channel ,它还代表将要创建的 goroutine 的数量。所有例程都从一个 channel 读取并写入另一个 channel ,主 goroutine 将打印来自最终 channel 的值。

1 个输入 channel --- N 个 goroutines 查找并添加到输入和输出 --- 1 个输出 channel

问题是我总是遇到死锁,因为我不知道如何关闭一个正在 self 馈送的 channel ,也不知道它什么时候会停止,所以我也无法关闭输出 channel 。

代码如下:

package main

const count = 3
const finalNumber = 100

// There will be N routines running and reading from the one read channel
// The finalNumber is not known, in this examples is 100, but in the main problem will keep self feeding until the operation gives a wrong output
// readingRoutine will feed read channel and the print channel
func readingRoutine(read, print chan int) {
    for i := range read {
        print <- i
        if i < finalNumber && i+count < finalNumber {
            read <- i + count
        }
    }
}

// This is the main routine that will be printing the values from the print channel
func printingRoutine(print chan int) {
    for i := range print {
        println(i)
    }
}

func main() {
    read := make(chan int, count)
    print := make(chan int, count)

    // Feed count numbers into the buffered channel
    for i := 0; i < count; i++ {
        read <- i
    }

    // count go routines will be processing the read channel
    for i := 0; i < count; i++ {
        go readingRoutine(read, print)
    }
    printingRoutine(print)
}

在此示例中,它应打印从 0 到 100 的所有数字并完成。 谢谢

最佳答案

您可以使用 sync.WaitGroup 来等待事情完成,例如 wg := &sync.WaitGroup{}

当您尝试打印 finalNumber 次时,您应该调用 wg.Add(finalNumber) 然后在 print() 中,每次完成打印后,调用 wg.Done()

生成另一个 goroutine 等待 wg.Wait() 然后关闭 read channel 和 print channel 。

func printingRoutine(print chan int,wg *sync.WaitGroup) {
    for i := range print {
        println(i)
        wg.Done()
    }
}

func main() {
    read := make(chan int, count)
    print := make(chan int, count)
    wg := &sync.WaitGroup{}
    wg.Add(finalNumber)

    // Feed count numbers into the buffered channel
    for i := 0; i < count; i++ {
        read <- i
    }

    // count go routines will be processing the read channel
    for i := 0; i < count; i++ {
        go readingRoutine(read, print)
    }
    go func() {
        wg.Wait()
        close(read)
        close(print)
    }()
    printingRoutine(print,wg)
}

Playground :https://play.golang.org/p/BMSfz03egx0

关于multithreading - 在 Go 中关闭自馈 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51715210/

有关multithreading - 在 Go 中关闭自馈 channel的更多相关文章

  1. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  2. ruby-on-rails - 在 seeds.rb 中关闭验证 - 2

    如何在seeds.rb中关闭Rails3.2.3中的验证?我这样做了u1=User.createemail:'my@email.com',password:'123',validate:false但它说无法批量分配protected属性:验证。我知道这是什么意思。那么我该如何摆脱这个错误呢? 最佳答案 你可以做到u1=User.new(email:'my@email.com',password:'123').save(validate:false) 关于ruby-on-rails-在se

  3. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  4. ruby-on-rails - Rails 4 中关于匹配关键字在 Rails 3 中工作的路由问题 - 2

    在rails3中,匹配关键字有效,但在rails4中,匹配关键字不适用于路由我如何在rails4中定义这些路由此代码段在rails3中运行match'admin',:to=>'access#menu'match'show/:id',:to=>'public#show'match':controller(/:action(/:id(.:format)))'我需要rails4的通用公式,就像在rails3中一样match':controller(/:action(/:id(.:format)))' 最佳答案 Rails4删除了通用匹配,

  5. 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_

  6. ruby - 在 Ruby 中关闭 SSL 证书验证 - 2

    使用“net/https”和ssl时,如何禁用生成的SSL证书的验证? 最佳答案 以下代码将禁用证书验证。请注意,这必然意味着将接受无效证书。http.verify_mode=OpenSSL::SSL::VERIFY_NONEifhttp.use_ssl? 关于ruby-在Ruby中关闭SSL证书验证,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/982329/

  7. 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

  8. ruby - 是否有必要在 ruby​​ 中关闭 StringIO? - 2

    我们是否需要在Ruby中使用后关闭StringIO对象以释放资源,就像我们处理真正的IO对象一样?obj=StringIO.new"somestring"#...obj.close#提炼我的问题关闭文件对象是必要的,因为它将关闭文件描述符。打开文件的数量在操作系统中是有限的,这就是为什么有必要关闭文件。但是,如果我理解正确的话,StringIO是内存中的抽象。我们需要关闭它吗? 最佳答案 StringIO#close不释放任何资源或删除对累积字符串的引用。因此调用它对资源使用没有影响。只有在垃圾回收期间调用的StringIO#fin

  9. DiFi: A Go-as-You-Pay Wi-Fi Access System 精读笔记(三) - 2

    IV.SYSTEMIMPLEMENTATIONWeadoptmodulardesignfollowingtheintegrationofblockchain.Itbringsmoreflexibilitybyseparatingtheimplementationofdifferentfunctionalities,sowecouldleveragetheadvantagesoftheblockchain-basedsmartcontractwhilereducingoverhead.Figure3illustrateshowdifferentmodulesareinvolvedintheint

  10. ruby-on-rails - 类似 Twitter 关注者/在 ActiveRecord 中关注的关系 - 2

    我试图在我的应用程序中表示用户之间的关系,其中一个用户可以有很多关注者并且可以关注其他用户。我想要像user.followers()和user.followed_by()这样的东西你能详细告诉我如何使用ActiveRecord表示这个吗?谢谢。 最佳答案 你需要两个模型,一个Person和一个FollowingsrailsgeneratemodelPersonname:stringrailsgeneratemodelFollowingsperson_id:integerfollower_id:integerblocked:boole

随机推荐