9

Ctrl-C が押されるまで永遠にループする非常に単純なサーバーを作成しています。ctrl-c のシグナル ハンドラーで開いているソケットを閉じてサーバーをシャットダウンしたいのですが、シグナル ハンドラーのスコープがわかりません。また、ソケットを宣言するという考えも好きではありません。 (s) グローバルになるには閉じる必要があります。

誰かが提案を提供できますか?これを行う標準的な方法はありますか?

4

2 に答える 2

9

シグナル ハンドラーがあるので、Unix バリアントを使用していると仮定します。もしそうなら:

  • ソケットは、int であるファイル番号によってカーネルに識別されます。を参照してくださいsocket(2)
  • そのintはあなたのプロセスに有効です
  • その int は、作成後にフォークされたすべてのプロセスに対して有効です
  • close-on-exec でない場合は、実行するすべてのプロセスに有効です。

したがって、シグナルハンドラーでは完全に有効です。使用する番号をシグナル ハンドラーに認識させる方法は、指定していない言語によって異なります。ほとんどすべての言語で機能する 2 つのアプローチがあります。

  • 終了する以外に行うクリーンアップがない場合はclose、exit を呼び出すだけです。または、シグナル アクションをデフォルトの exit に設定します。カーネルはソケットを閉じます。
  • 選択/ポーリングループにクリーンアップして終了するように指示するために、フラグ (通常は何らかのグローバルになります) を設定します。プログラムのさまざまな部分がシグナル ハンドラから安全に呼び出せるかどうかを心配する必要がないという利点があります。
于 2009-01-16T06:04:10.037 に答える
9

通常、シグナル ハンドラーでは何もしないことをお勧めします。フラグを設定する以外に。

その後、制御がメイン ループに戻ったときに、このフラグを調べ、ループを終了し、ソケットを閉じ、オブジェクトに対してデストラクタを実行し、正常に終了できます。

シグナル ハンドラーは、C または C++ ライブラリ呼び出しの途中など、ほぼいつでも呼び出される可能性があり、これが問題になる可能性があります。

于 2009-01-16T07:02:07.440 に答える