我正在用 golang 编写一个小工具,它读取 CSV 文件并将每一行传递给一个通道。每行都有一个接收器 go-routine。不知何故,这非常慢 - 使用分析我发现该程序在 runtime.usleep 上的运行率为 68%。我的代码中没有“睡眠”。
有人可以指出这可能来自哪里,它意味着什么以及如何摆脱它?
(pprof) top10
28.98s of 30.12s total (96.22%)
Dropped 64 nodes (cum <= 0.15s)
Showing top 10 nodes out of 44 (cum >= 19.38s)
flat flat% sum% cum cum%
20.53s 68.16% 68.16% 20.53s 68.16% runtime.usleep
6.86s 22.78% 90.94% 6.86s 22.78% syscall.Syscall
0.30s 1% 91.93% 0.30s 1% runtime/internal/atomic.Cas64
0.28s 0.93% 92.86% 0.28s 0.93% runtime.mach_semaphore_signal
0.26s 0.86% 93.73% 19.15s 63.58% runtime.findrunnable
0.24s 0.8% 94.52% 0.24s 0.8% runtime.mach_semaphore_wait
0.21s 0.7% 95.22% 17.11s 56.81% runtime.runqgrab
0.13s 0.43% 95.65% 0.23s 0.76% runtime.runqempty
0.12s 0.4% 96.05% 4.17s 13.84% runtime.lock
0.05s 0.17% 96.22% 19.38s 64.34% runtime.schedule
(pprof)
相关源代码:
[...snip from main...]
var wg_p sync.WaitGroup
var wg_w sync.WaitGroup
for i := 0; i < workercount; i++ {
wg_p.Add(1)
go func(i int) {
processor(i, chn_read, chn_write)
wg_p.Done()
}(i)
}
wg_w.Add(1)
go func() {
writer(chn_write)
wg_w.Done()
}()
// read headers/1st line from csv
headers, _ := csvf.Read()
g_fieldnames = headers
chn_write <- g_fieldnames
// read 'n feed linewise
for {
chunk, _ := csvf.Read()
if chunk == nil {
close(chn_read)
break
}
chn_read <- chunk
}
[...snip end from main...]
和 go-routines
func processor(num_p int, chn_read chan []string, chn_write chan []string) {
for msg := range chn_read {
// snipped working on 'msg'
chn_write <- msg
}
}
func writer(chn_write chan []string) {
fout, _ := os.Create("./out.csv")
defer fout.Close()
w := csv.NewWriter(fout)
counter := 0
for msg := range chn_write {
w.Write(msg)
counter++
}
w.Flush()
}