6
gcc (GCC) 4.7.2
c89

ファイルが既に閉じられているかどうかを確認することはできますか?

を使用してファイルを開き、 を使用fopen()して閉じfclose(fd)ました。

このファイルは、プログラムの実行中に開いたり閉じたりします。ただし、ユーザーはctrl-c.

クリーンアップ ルーチンに移動すると、ファイルが開いているか閉じているかわかりません。したがって、fclose(fd)2 回実行しようとすると、スタック ダンプが発生します。

私が投げかけているいくつかのアイデア:

  1. 開いているか閉じているかの状態をファイルに追加し、その状態を確認します。これは、このような単純なジョブの作業が増えることを意味します。
  2. プログラムの終了時に OS が自動的にクリーンアップするため、何もしないでください。
  3. アクセス機能はありますが、それはモードをチェックするだけです。

よろしくお願いします。

4

5 に答える 5

7

私の知る限り、glibc はFILE*変数を検証する方法を提供していません。

ある種の状態を維持するか、単に設定fdするだけNULLで機能しますが、ファイルを閉じた直後ではなく、リセットする前にクリーンアップルーチンに入らないように注意する必要がありますfd。Ctrl+C はシグナル (SIGINT) をプログラムに送信するため、ファイルが閉じられて fd がリセットされている間、シグナルをブロックすることができます。したがって、fcloseメインプログラムは次のようになります。

// 1. Block SIGINT
sigset_t old_mask, to_block;
sigemptyset(&to_block);
sigaddset(&to_block, SIGINT);
sigprocmask(SIG_BLOCK, &to_block, &old_mask);

// 2. Close the file and reset fd
fclose(fd);
fd = NULL;

// 3. Restore signal handling
sigprocmask(SIG_SETMASK, &old_mask, NULL);

そして、クリーンアップルーチンでは、次のことを確認する必要がありますfd

if (fd != NULL) fclose(fd);

プログラムがマルチスレッドの場合は、pthread_sigmask代わりに使用する必要があります。

fcloseall()あなたの場合、クリーンアップルーチンでの単純な呼び出しははるかに簡単です。

あなたの質問で意味されている2番目のオプションについては、何もしないことについてです-まあ、OSはあなたのプログラムのすべてをクリーンアップします。唯一の欠点は、開いている書き込みストリームがあった場合、一部のデータがディスクに書き込まれない可能性があることです。しかし、おそらく Ctrl+C の場合は問題ありません。

于 2013-07-30T08:16:42.147 に答える
4

あなたの心に少し混乱があるように思えます。

fopenfclosef...関数で使用されるファイル ハンドラーは、プロセス スコープです。つまり、それらはアプリケーション内で有効です (通常)。

ファイルを開くと、成功するかどうかという 2 つのことが起こります。成功した場合は、ファイルを排他的に使用しているか、他のプロセスと共有している可能性があります。失敗した場合は、別のプロセスがすでにファイルを使用している可能性があります。検索し_fsopenます。

プロセスが通常どおりまたは中断されて ( のようにCtrl+C) 終了すると、遅かれ早かれ OS はプロセスに関連付けられたリソースを解放します。これは、ファイル ハンドラー、メモリなどに適用されます。

ご質問の件ですが、アプリケーションが正常に終了した場合でも、終了した場合でもCtrl+C、閉じられていないファイル ハンドラは OS によって解放されます。

アプリケーションが起動するたびに、必要なファイル ハンドラを開く必要があります。OSはそれらを開いたままにしません。

于 2013-07-30T09:10:15.133 に答える