2

アプリケーションが着信接続を監視し、xml ドキュメントで定義されているいくつかのルールを適用するプロジェクトを実行する必要があります。ルールは、接続をフィルタリング (ブロックまたは許可) するか、特定のポートでトラフィックをリダイレクトします。これを行うために、accept や recv (Winsock から) などの関数を使用します。これらの関数はすべて、異なるスレッドで使用されます。ただし、これらすべてのブロッキング呼び出しが行われるため、終了する前にプログラムをどのようにクリーンアップする必要があるのか​​ 疑問に思っています。通常、ユーザーが X ボタンを押してコンソールを終了するまで待つか、ユーザーがメイン スレッドで特定の文字を入力するのを待ちます。問題は、アクティブなスレッドがまだ存在するときにアプリケーションが終了した場合/メモリがまだ割り当てられている場合/ソケットが使用されている場合に何が起こるかわかりません。すべてのデストラクタが呼び出されますか? ハンドルとソケットが正しく閉じられていますか? それとも、どうにかして自分でやる必要がありますか?

ありがとう

4

2 に答える 2

1

一般的に、私はノーと言うでしょう。絶対に強制されない限り、ソケット、fd、ハンドル、スレッドなどのリソースを明示的にクリーンアップしようとしないでください。

正確な動作は、OS とアプリの終了方法によって異なります。

すべての一般的なデスクトップ OS は、プロセスが終了すると、OS によってプロセスに割り当てられたリソースを解放します。これには、ソケット、ファイル記述子、メモリが含まれます。

Windows/Linux では、明示的なクリーンアップを行わずに C/C++ main() から戻ると、crt コードによって静的 dtor が呼び出されます。非メイン スレッドで動的に割り当てられたオブジェクトの Dtor は実行されません。

他の言語で記述された実行可能ファイルは、異なる動作をする場合があります。

main() から戻る代わりに、'ProcessExit()' API を直接呼び出すと、OS には dtors の概念がないため、静的デストラクタは呼び出されません。実行可能ファイルを生成します。

どちらの場合でも、OS が呼び出されてプロセスが終了します。OS はこれを行います (単純な「ダミー」バージョン :)、最初に、実行されていないすべてのプロセス スレッドの状態を変更して、二度と実行されないようにします。その後、他のコアで実行されているスレッドが停止されます。次に、fd、ソケットなどの OS リソースが閉じられてから解放され、すべてのプロセス メモリが解放され、次に OS カーネル プロセス/スレッド オブジェクトが解放され、プロセスが存在しなくなります。

一部またはすべてのスレッドがアプリを停止する必要があるときに呼び出される C++/dtors が絶対に必要な場合は、dtors を実行できるように、他のスレッドに明示的に停止するように通知する必要があります。関連するブロッキング呼び出しが戻った直後にチェックする、グローバルにアクセス可能な「CloseRequested」ブールを使用する傾向があります。ブロッキング呼び出しを戻すよう説得するという問題が残っています。

一部のブロッキング呼び出しは、複数のシグナルを待機するようにコーディングできるため、単純なイベント/sema/condvar/その他のシグナルによって呼び出しを返すことができます。

recv()、accept() などの一部の呼び出しは、待機している fd/socket を閉じることで早期に戻るように説得できます。

一部の呼び出しは、待機条件を「人為的に」満たして戻るようにすることができます。「CloseRequested」ブールをチェックできるように、フォルダーモニター呼び出しを返すためだけに一時ファイルを作成します。

ブロッキング呼び出しが非常に頑固で、戻るように説得できない場合は、アプリを再設計して、dtors で解放された重要なリソースが別のスレッドによって解放されるようにすることができます。別のスレッドで物を作成して渡すことができます。 ctor パラメーターでブロックするスレッドに、そのようなものです。

注: 上記のスレッド シャットダウン コード ボッジは、アプリの通常の機能に追加されない余分なコードです。明示的なスレッドのシャットダウンは、明示的なユーザー コード (DB 接続など) によって絶対に解放する必要があるリソースを保持するスレッドに制限する必要があります。OS がリソースを解放できる場合は、それを許可する必要があります。OS は、使用しているリソースを解放する前にすべてのプロセス スレッドを停止するのに非常に優れていますが、ユーザー コードはそうではありません。

于 2013-04-11T08:50:44.893 に答える