2010-07-06 176 views
2

我有一個多線程的應用程序運行在Win XP上。在某個階段,其中一個線程無法使用fopen函數打開現有文件。 _get_errno函數返回EMFILE,這意味着打開的文件過多。沒有更多文件描述符可用。 FOPEN_MAX我的平臺是20 _getmaxstdio返回512我的WinDbg覈實這一點,我看到約100文件打開:fopen問題 - 太多打開的文件

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); 
     } 
    } 
} 
+0

也許Windows對每個進程有512個描述符的限制(stdin和stdout減2)。也許使用線程也會消耗一些描述符。在這一點上,我只能猜測。我遠不是Windows內核專家。 – ereOn 2010-07-06 12:29:04

+0

你可以編輯你的問題,無需將源代碼寫入註釋 – codymanix 2010-07-07 11:20:49

回答

1

我想在win32中,所有的crt函數最終都會使用win32 api底下。所以在這種情況下,最有可能的是它必須使用win32的CreateFile/OpenFile。現在,CreatFile/OpenFile api不僅適用於文件(文件,目錄,通信端口,管道,郵件插槽,驅動器卷等)。因此,在實際應用中,根據數量的不同,這些資源的最大打開文件可能有所不同。由於你沒有描述太多的應用程序。這是我的第一個猜測。如果時間許可通過這個http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx

5

我想這是您的操作系統的限制。它可以依賴於很多東西:文件描述符的表示方式,它們消耗的內存等等。

而且我想你可以做的事情不多。也許有一些參數來調整這個限制。

真正的問題是,你是否真的需要同時打開那麼多文件?我的意思是,即使你有100多個線程試圖讀取100多個不同的文件,他們可能也無法同時讀取它們,你可能得不到比任何更好的結果,例如50個線程。

因爲我們不知道你想達到什麼,所以很難做到更準確。

+0

在我開始系統微調之前,我想了解是什麼導致問題以及爲什麼打開文件的最大數量不是常數(它在95和103之間變化)。影響這個的其他因素是什麼,例如事件,信號量或目錄句柄? – tommyk 2010-07-06 08:16:59

+0

@tommyk:這只是一個猜測,我對你的操作系統沒有深入的瞭解(主要是因爲你沒有說你是在Windows,Linux還是其他的:D)。我假定在某些系統下,文件描述符是全局的,因此可用描述符(套接字,文件,互斥鎖等)的數量受其他進程和操作系統本身的限制。 – ereOn 2010-07-06 08:49:36

+0

我的平臺是Windows XP(32位)。 – tommyk 2010-07-06 12:02:47