4

Win XP でマルチスレッド アプリケーションを実行しています。特定の段階で、スレッドの 1 つが 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関数が最終的にその下のwin32apiを使用するようになると思います。したがって、この場合、おそらくwin32のCreateFile/OpenFileを使用している必要があります。現在、CreatFile / OpenFile apiは、ファイル(ファイル、ディレクトリ、通信ポート、パイプ、メールスロット、ドライブボリュームなど)のみを対象としているわけではありません。したがって、実際のアプリケーションでは、これらのリソースの数に応じて、最大オープンファイルが異なる場合があります。あなたはアプリケーションについてあまり説明していないので。これが私の最初の推測です。時間が許せば、このhttp://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspxを通過してください

于 2010-07-08T09:27:27.810 に答える