我有以下部分代码不会将任何数据写入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()
}
答案 0 :(得分:2)
两个明显的错误:
主例程不等待其他goroutine,当主例程返回时,程序终止,这就是log.txt为空的原因。 sync.WaitGroup
可能会有所帮助。
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()
}
中还有一些额外的信息