go - 我在 golang 中错误地使用了 channel 吗?

标签 go channel

我来自 Node.js 背景,在那里做一些异步工作非常容易,然后在完成长时间运行的任务后做更多的工作,我确信它在 Go 中是一样的,但我只是没有'我还没有完全了解 channel 的运作方式。

我正在为我玩的一个老游戏构建一个解析器,它分析拍卖数据日志中的行并解析它们以通过套接字 io 流式传输到网站上的实时提要。一个文件一次可以发送 100 行,我的解析器必须一次分析每一行并从每一行中提取元信息(例如商品、商品价格等)

每一行都有这个 for 循环针对它运行(这假设项目列表的部分是从正则表达式派生的):

itemChannel := make(chan Item)

for _, itemName := range itemList {
    item := Item {
        Name: itemName,
    }

    // Long running method which does parsing for the item such as pricing, quantity and makes some http calls (runs 75ms on average)
    go item.FetchData(itemChannel)

    // Read from the channel when its done
    raw := <-itemChannel
    auction.Items = append(auction.Items, raw)
    auction.Seller = seller
}

auctions = append(auctions, auction)
fmt.Println("Appended auction: ", auction)
go c.publishToRelayService(auction)

现在(根据观察)好像raw := <-itemChannel导致循环阻塞,直到 goroutine 完成并将其数据传回(这肯定意味着以 item.FetchData(itemChannel) 运行会做同样的事情。当数据返回到 channel 中时,我如何从 channel 中读取数据,但跳出循环迭代作为尽可能快。有些行中有 15-20 个项目,这导致程序在解析下一行之前暂停约 2-3 秒。我希望能够比那更快地中断并处理下一行使解析器尽可能快。是否有任何类似于 Node 中的 Promises 的机制,我可以在其中将完成处理程序链接到 item.FetchData() 的每个完成?

注意 fetchChannel当所有获取工作完成后,将写入我的 Item 类型内部。

最佳答案

您可以编写一个不同的 go 例程来等待 channel 中的新数据并对其进行处理。 这样生产者和消费者并行运行,当生产者完成生产消费者时必须完成,因为这里消费者是一个轻进程

您可以使用done channel 来指示消费者已完成

这里是你可以如何修改代码

itemChannel := make(chan Item)
done := make(chan bool)
//Consumer
go func(channel chan Item) {
    for raw := range channel {
        auction.Items = append(auction.Items, raw)
        auction.Seller = seller
        auctions = append(auctions, auction)
    }
    done <- true
}(itemChannel)

//Producer
for _, itemName := range itemList {
    item := Item{
        Name: itemName,
    }

    // Long running method which does parsing for the item such as pricing, quantity and makes some http calls (runs 75ms on average)
    go item.FetchData(itemChannel)

}

<-done
fmt.Println("Appended auction: ", auction)
go c.publishToRelayService(auction)

关于go - 我在 golang 中错误地使用了 channel 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41754198/

相关文章:

java - 一个 netty 缓冲区问题中包含多条消息

sorting - sort.Slice排序不正确

docker - 使用自定义 Dockerfile : no such image 运行测试容器

java - Android (Java) : Parse. com 没有订阅不是硬编码字符串的 channel ?

go - 无法在Go例程中获取多个 channel 值

go - 了解 golang 并发上下文中 channel 的正确使用

ffmpeg 将具有 8 个音频 channel 的视频文件转换为多 channel wav

go - 在 Go 中等待用户输入时如何打印到控制台?

http - Golang clean items out of channel 不会被读取

go - 真的不需要为 bcrypt 生成盐吗?