登录
首页 >  Golang >  Go问答

将文件的多行内容分发给多个 goroutine:如何实现?

来源:stackoverflow

时间:2024-02-22 20:54:24 465浏览 收藏

IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《将文件的多行内容分发给多个 goroutine:如何实现?》,聊聊,我们一起来看看吧!

问题内容

我想读取一个巨大的文件,比如说 > 1 gb,并让多个工作协程处理它的行。

我担心,当使用大量的工作 goroutine 时,使用单个 goroutine(main)来读取输入行会造成瓶颈。

如何安全地让多个 goroutine 读取文件的行?是否可以将输入文件分成几个块,并让每个 goroutine 分别对一个单独的块进行操作?

以下是让一个 goroutine 读取输入行并由多个 worker goroutine 处理它们的示例代码:

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
)

func main() {
    file, err := os.Open("/path/to/file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    lines := make(chan string)

    for i := 0; i < 100; i++ {
        // start 100 workers to process input lines.
        // the workers terminate once 'lines' is closed.
        go worker(lines)
    }

    scanner := bufio.NewScanner(file)
    go func() {
        defer close(lines)
        for scanner.Scan() {
            lines <- scanner.Text()
        }

        if err := scanner.Err(); err != nil {
            log.Fatal(err)
        }
    }()

    ...
}

解决方案


首先,并发读取文件是没有意义的。如果你需要对行数据进行复杂的操作,你应该做的是顺序读取文件并将行的内容发送到每个 goroutine。

为了优化这个过程,您应该改变不同的东西。您需要改变的第一件事是工人数量。该值不是随机设置的,为了达到计算机的最大性能,请使用:

for i := 0; i < runtime.gomaxprocs(0); i++ {
    go worker(lines)
}

这样您就可以有效地使用计算机上可用的 cpu。 最后,要处理每行的所有数据,您必须添加:

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer close(lines)
    for scanner.Scan() {
        wg.Add(1)
        lines <- scanner.Text()
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
    wg.Done()
}()
wg.Wait()

在工作函数内部,您还将在末尾添加一个 wg.done()

希望这对您有帮助!

理论要掌握,实操不能落!以上关于《将文件的多行内容分发给多个 goroutine:如何实现?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>