Go 戈兰:同时处理5个大文件

Go 戈兰:同时处理5个大文件,go,Go,我目前用Perl处理了5个巨大的日志文件(每个日志文件有400万行),我想我可以尝试在Go及其并发特性中实现相同的日志文件。所以,由于对围棋非常缺乏经验,我想做以下几点。如对该方法有任何意见,将不胜感激。 一些粗略的伪代码: var wg1 sync.WaitGroup var wg2 sync.WaitGroup func processRow (r Row) { wg2.Add(1) defer wg2.Done() res = <process r>

我目前用Perl处理了5个巨大的日志文件(每个日志文件有400万行),我想我可以尝试在Go及其并发特性中实现相同的日志文件。所以,由于对围棋非常缺乏经验,我想做以下几点。如对该方法有任何意见,将不胜感激。 一些粗略的伪代码:

var wg1 sync.WaitGroup
var wg2 sync.WaitGroup

func processRow (r Row) {
    wg2.Add(1)
    defer wg2.Done()
    res = <process r>
    return res
}

func processFile(f File) {
    wg1.Add(1)
    open(newfile File)
    defer wg1.Done()
    line = <row from f>
    result = go processRow(line)
    newFile.Println(result) // Write new processed line to newFile
    wg2.Wait()
    newFile.Close()

}

func main() {

    for each f logfile {
        go processFile(f)
    }
    wg1.Wait()
}
var wg1 sync.WaitGroup
var wg2 sync.WaitGroup
func processRow(r行){
wg2.添加(1)
推迟wg2.Done()
res=
返回res
}
func进程文件(f文件){
wg1.添加(1)
打开(新文件)
延迟wg1.Done()
行=
结果=转到进程行(行)
Println(result)//将新处理的行写入newFile
wg2.Wait()
newFile.Close()
}
func main(){
对于每个f日志文件{
转到进程文件(f)
}
wg1.Wait()
}
所以,我的想法是并发地处理这5个文件,然后每个文件的所有行也将被并发地处理


这行吗?

您肯定应该使用通道来管理已处理的行。或者,您也可以编写另一个goroutine来处理输出

var numGoWriters = 10

func processRow(r Row, ch chan<- string) {
    res := process(r)
    ch <- res
}

func writeRow(f File, ch <-chan string) {
    w := bufio.NewWriter(f)
    for s := range ch {
        _, err := w.WriteString(s + "\n")
    }

func processFile(f File) {
    outFile, err := os.Create("/path/to/file.out")
    if err != nil {
        // handle it
    }
    defer outFile.Close()
    var wg sync.WaitGroup
    ch := make(chan string, 10)  // play with this number for performance
    defer close(ch) // once we're done processing rows, we close the channel
                    // so our worker threads exit
    fScanner := bufio.NewScanner(f)
    for fScanner.Scan() {
        wg.Add(1)
        go func() {
            processRow(fScanner.Text(), ch)
            wg.Done()
        }()
    }
    for i := 0; i < numGoWriters; i++ {
        go writeRow(outFile, ch)
    }
    wg.Wait()  
}

对于i/o绑定的任务,您可能无法从CPU并发性中获得那么多。你可能也想看看频道。什么是“流程r”?如果这是一件相对“容易”的事情,那么在单独的gorutine中进行可能不值得——开销大于收益。此外,结果是,您会有一个“日志数据集”(即所有5个文件合并为一个)还是会有5个不同的结果集?@ain我的理解是,这将是非常不实际的。goroutines的开销非常低。@salvador:不,不难实现,但我不会在下周中旬之前进入开发环境。我很想知道其他人对这个想法的看法。@ain将有5个独立的结果文件,每个源文件一个。同样,“处理r”也很容易,但是还有一些处理要做。e、 g正则表达式,从十六进制转换为十进制,在CSV中输出非常感谢您!
func main() {
    var wg sync.WaitGroup

    filenames := [...]string{"here", "are", "some", "log", "paths"}
    for fname := range filenames {
        inFile, err := os.Open(fname)
        if err != nil {
            // handle it
        }
        defer inFile.Close()
        wg.Add(1)
        go processFile(inFile)
    }
    wg.Wait()