4

我有一个在 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); 
        } 
    } 
}
4

2 回答 2

5

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

我想你对此无能为力。也许有一些参数可以调整该限制。

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

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

于 2010-07-06T07:40:12.337 回答
2

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

于 2010-07-08T09:27:27.810 回答