English 中文(简体)
戈兰高地 Go 常规与等候组一起执行相同代码两次
原标题:Golang Go Routine with WaitGroup executes same code twice

我比较新 要去 和有一些麻烦 与一些同时代码:

出于某种原因,其他区块执行两次,而程序恐慌则带有以下信息: panic:关闭闭路通道 ,因为 expactedCh 第一次已经关闭。

func (ex Extractor) Extract(pageCh chan *types.ScrapedData, extractedCh chan *types.ScrapedData) {
    log.Info().Msg("Extracting data...")

    var wg sync.WaitGroup

    for {
        page, more := <-pageCh
        if more {
            wg.Add(1)

            go func() {
                defer wg.Done()
                worker, err := ex.getWorker(page)
                if err != nil {
                    log.Error().Err(err).Msg("Error creating worker")
                } else {
                    worker.Extract(extractedCh)
                }
            }()

        } else {
            log.Info().Msg("WebPage channel closed: waiting for waitgroup")
            wg.Wait()

            log.Info().Msg("WaitGroup finished closed -- closing extractedCh")
            close(extractedCh)
        }

    }

}

抽取函数只以一个运行程序运行 - 所以我不知道为什么其它块执行两次, 并试图关闭已经关闭的 < code> Exctracted Ch 。

答案是什么:我是要重组我的代码, 还是简单地检查频道关闭前是否关闭?

问题回答

其它区块第二次执行, 因为当 < code> pageCh 关闭时, 其它区块不会打破循环 。 通过添加一个 < code> return 语句来修正其它区块的结尾。 最好还是重写这样的代码 :

func (ex Extractor) Extract(pageCh chan *types.ScrapedData, extractedCh chan *types.ScrapedData) {
    log.Info().Msg("Extracting data...")
    var wg sync.WaitGroup
    for page := range pageCh {
        wg.Add(1)
        page := page // delete this line if compiling for Go 1.22 or later
        go func() {
            defer wg.Done()
            worker, err := ex.getWorker(page)
            if err != nil {
                log.Error().Err(err).Msg("Error creating worker")
            } else {
                worker.Extract(extractedCh)
            }
        }()
    }
    log.Info().Msg("WebPage channel closed: waiting for waitgroup")
    wg.Wait()
    log.Info().Msg("WaitGroup finished closed -- closing extractedCh")
    close(extractedCh)
}

pageCh 关闭时循环退出。

可能会造成混乱的一件事就是这条线:

    page, more := <-pageCh

频道接收的第二个返回值表示“ 收到一个值 ”, 而不是“ 更多预期值 ” 。 如果第二个返回值是 < code> false , 意思是“ 未收到值 ”, 那么在频道上接收的返回值将永远返回第二个返回值中的 < code> false





相关问题
Antlr3 - HIDDEN token in the parser

Can you use a token defined in the lexer in a hidden channel in a single rule of the parser as if it were a normal token? The generated code is Java... thanks

TcpChannel registration problem

I ve read here: Error 10048 when trying to open TcpChannel I am having what I thought to be a similar problem - apparently not. I took the advice of the first respondant to reset winsock (how does ...

get FileChannel without using java.io.* (use pure NIO)

Recently I got a comment to this answer that I should stay away from java.io if I want to use "pure NIO". This is the simplified code (copy a file): private static void copy(File source, File ...

WCF ChannelFactory State Property

What does it mean for a ChannelFactory to have a State property? I understand that a created channel can have connection based states. But am confused as to why the ChannelFactory also has such ...

WCF channel lifetime with repeat calls

Maybe this is an obvious question, maybe it isn t. Imagine a GUI control application where every button push calls a different function on a remote WCF service. Button usage is frequent at ...

WCF duplex channel gets closed when using callbacks

My WCF service uses netTcpBinding, and has a callback object. I need to service multiple concurrent clients, and mantain sessions, so the service is decorated with [ServiceBehavior(...

Shared memory vs. Go channel communication

One of Go s slogans is Do not communicate by sharing memory; instead, share memory by communicating. I am wondering whether Go allows two different Go-compiled binaries running on the same machine to ...

热门标签