douyouchou1085 2016-08-08 08:52
浏览 172

golang在go函数中打开文件过多,goroutine [关闭]

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()
}

If you run the program brings up the following error. "open $ too many open files" Please tell us how to eliminate the error.

  • 写回答

1条回答 默认 最新

  • duanqin2026 2016-08-08 09:24
    关注

    You are running out of system resources because you are using up too many file descriptors without releasing enough of them. You need to limit concurrency in your program.

    For this, you can have a buffered channel that acts as a counting semaphore.

    sem := make(chan struct{}, 12) // 12 is the maximum number of 
                                    // concurrent processes that may run at any time
    

    Now you can modify your method as:

    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)
    }
    

    Your use of wg.Done is also incorrect. Read about it here

    (Note that this code is to give a basic idea about this kind of problem. You can also refer to this question for a working example: Go worker pool with repetitive queue structure

    评论

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端