【问题标题】:fopen problem - too many open filesfopen 问题 - 打开的文件太多
【发布时间】:2010-07-06 07:36:15
【问题描述】:

我有一个在 Win XP 上运行的多线程应用程序。在某个阶段,一个线程无法使用 fopen 函数打开现有文件。 _get_errno 函数返回 EMFILE,这意味着 打开的文件太多。没有更多的文件描述符可用。我的平台的 FOPEN_MAX 是 20。_getmaxstdio 返回 512。我用 WinDbg 进行了检查,发现大约有 100 个文件处于打开状态:

788 Handles
Type            Count
Event           201
Section         12
File            101
Port            3
Directory       3
Mutant          32
WindowStation   2
Semaphore       351
Key             12
Thread          63
Desktop         1
IoCompletion    6
KeyedEvent      1

fopen 失败的原因是什么?


编辑:

我编写了简单的单线程测试应用程序。这个应用程序可以打开 510 个文件。我不明白为什么这个应用程序可以打开比多线程应用程序更多的文件。会不会是因为文件句柄泄露?

#include <cstdio> 
#include <cassert> 
#include <cerrno> 
void main() 
{ 
    int counter(0); 

    while (true) 
    { 
        char buffer[256] = {0}; 
        sprintf(buffer, "C:\\temp\\abc\\abc%d.txt", counter++); 
        FILE* hFile = fopen(buffer, "wb+"); 
        if (0 == hFile) 
        { 
            // check error code 
            int err(0); 
            errno_t ret = _get_errno(&err); 
            assert(0 == ret); 
            int maxAllowed = _getmaxstdio(); 
            assert(hFile); 
        } 
    } 
}

【问题讨论】:

  • 也许 Windows 对每个进程有 512 个描述符的限制(对于 stdinstdout,减 2)。也许使用线程也会消耗一些描述符。在这一点上,我只能猜测。我远不是 Windows 内核专家。
  • 您可以编辑您的问题,无需将源代码写入cmets

标签: c++ windows fopen file-descriptor


【解决方案1】:

我猜这是您的操作系统的限制。它可能取决于很多因素:文件描述符的表示方式、它们消耗的内存等等。

而且我想您对此无能为力。也许有一些参数可以调整这个限制。

真正的问题是,你真的需要同时打开那么多文件吗?我的意思是,即使您有 100 多个线程试图读取 100 多个不同的文件,它们也可能无法同时读取它们,并且您可能不会得到比拥有 50 个线程更好的结果.

很难更准确,因为我们不知道您要达到什么目标。

【讨论】:

  • 在开始系统微调之前,我想了解导致问题的原因以及为什么打开文件的最大数量不是恒定的(它在 95 和 103 之间变化)。影响这一点的其他因素是什么,例如事件、信号量或目录句柄?
  • @tommyk:这只是一个猜测,我对你的操作系统没有深入的了解(主要是因为你没有说你是在 Windows、Linux 还是其他系统上:D)。我假设在某些系统下,文件描述符是全局的,因此可用描述符(套接字、文件、互斥体等)的数量受到其他进程和操作系统本身的限制。
  • 我的平台是 Windows XP(32 位)。
【解决方案2】:

我认为在 win32 中所有 crt 函数最终都会使用下面的 win32 api。所以在这种情况下很可能它必须使用win32的CreateFile/OpenFile。现在 CreatFile/OpenFile api 不仅仅适用于文件(文件、目录、通信端口、管道、邮件槽、驱动器卷等)。因此,在实际应用程序中,根据这些资源的数量,您的最大打开文件可能会有所不同。由于您没有对应用程序进行太多描述。这是我的第一个猜测。如果时间允许,通过这个http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    相关资源
    最近更新 更多