package main
import (
"os"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(1024 * 1024)
for i := 0; i < (1024 * 1024); i++ {
go func(index int) {
if f, e := os.Open(i); e == nil {
//blah blah
f.Close()
}
}(i)
}
wg.Done()
}
如果运行该程序会出现以下错误。 “打开太多打开的文件” 请告诉我们如何消除错误。
答案 0 :(得分:5)
您的系统资源不足,因为您使用了太多的文件描述符而没有释放足够的文件描述符。您需要限制程序中的并发性。
为此,您可以使用缓冲通道作为计数信号量。
sem := make(chan struct{}, 12) // 12 is the maximum number of
// concurrent processes that may run at any time
现在您可以将方法修改为:
func main() {
var wg sync.WaitGroup
wg.Add(1024 * 1024)
for i := 0; i < (1024 * 1024); i++ {
go func(index int) {
// if there are already 12 goroutines running, below send will block
// and a new file wont be open
sem <- struct{}{}
// once this goroutine finishes, empty the buffer by one
// so the next process may start (another goroutine blocked on
// above send will now be able to execute the statement and continue)
defer func() { <-sem }()
// wg.Done must be deferred after a read from sem so that
// it executes before the above read
defer wg.Done()
if f, e := os.Open(strconv.Itoa(index)); e != nil {
// handle file open failure
return
}
defer f.Close()
// handle open file
}(i)
}
wg.Wait()
close(sem)
}
您对wg.Done
的使用也不正确。阅读它here
(请注意,此代码旨在提供有关此类问题的基本概念。您还可以参考此问题以获取一个有效的示例:Go worker pool with repetitive queue structure