Golang:为什么以下代码片段不写入文件?

时间:2017-02-22 06:36:58

标签: go

我有以下部分代码不会将任何数据写入log.txt文件。我不明白为什么?它不应该是同步问题,因为我在启动任何go例程之前关闭文件并在每个例程中打开/关闭文件。

package main

import (
    "fmt"
    "runtime"
    "os"
    "time"
)

func main() {
    runtime.GOMAXPROCS(4)

    f, _ := os.Create("./log.txt")
    f.Close()

    logCh := make(chan string, 50)

    go func() {
        for {
            msg, ok := <- logCh
            if ok {
                logTime := time.Now().Format(time.RFC3339)

                f, _ := os.OpenFile("./log.txt", os.O_APPEND, os.ModeAppend)

                f.WriteString(logTime + " - " + msg)

                f.Close()

            } else {
                break
            }
        }
    }()


    for i:=1; i < 10;i++ {
        for j:=1; j<10;j++ {
            go func(i, j int) {
                msg := fmt.Sprintf("%d + %d = %d\n", i, j, i+j)
                logCh <- msg
                fmt.Print(msg)
            }(i, j)
        }
    }


    //fmt.Scanln()
}

2 个答案:

答案 0 :(得分:2)

两个明显的错误:

  1. 主例程不等待其他goroutine,当主例程返回时,程序终止,这就是log.txt为空的原因。 sync.WaitGroup可能会有所帮助。

  2. msg, ok := <- logCh,当ok关闭且为空时,false仅为logCh。而且你没有打电话给close(logCh)

答案 1 :(得分:1)

首先,您需要等待频道清空。在这种情况下,您也不需要缓冲通道。使用WaitGroup

其次,在忽略错误的同时打开和关闭每个goroutine中的文件是实际问题。您不需要每次都打开和关闭文件。打开一次,写入后同步。

这有效:

package main

import (
    "fmt"
    "os"
    "runtime"
    "sync"
    "time"
)

func main() {
    runtime.GOMAXPROCS(4)

    f, _ := os.Create("./log.txt")
    defer f.Close()

    logCh := make(chan string)
    var wg sync.WaitGroup

    for i := 1; i < 10; i++ {
        for j := 1; j < 10; j++ {
            wg.Add(1)
            go func(i, j int) {
                defer wg.Done()
                msg := fmt.Sprintf("%d + %d = %d\n", i, j, i+j)
                logCh <- msg
                fmt.Print(msg)

            }(i, j)
        }
    }

    go func() {
        for {
            msg, ok := <-logCh
            if ok {
                logTime := time.Now().Format(time.RFC3339)

                f.WriteString(logTime + " - " + msg)
                f.Sync()

            } else {
                break
            }
        }
    }()

    wg.Wait()

    //fmt.Scanln()
}

this question

中还有一些额外的信息