2012-01-26 17 views
4

ソケットを使用するAPIを作成しています。 APIでは、さまざまなアイテムにメモリを割り当てます。私はソケットを閉じて、Ctrl-Cのようなシグナルがある場合にはメモリを解放することを確認したい。これを調べると、free()は安全な関数リスト(man 7シグナル)にないように見えます。したがって、シグナルハンドラ内のメモリを解放することはできません。私はちょうど良いソケットを閉じることができます。どのように私はメモリを解放することができるかについての任意の考えを持っていますか?あなたの時間のために事前にありがとうございます。シグナルハンドラ内でメモリを解放する

+0

信号から生き残る予定ですか? – frankc

+0

いいえ。私はちょうど失敗する前にメモリとソケットをきれいにしたかった – Mike

答えて

5

また、シグナルをキャッチせず、OSにプロセスのクリーンアップ中に行うようにクリーンアップを処理させてください。プロセスに直接結びついていないリソースを解放しているわけではありませんので、手動で解放する必要は特にありません。

+0

あなたとRが言ったことはいいと思います。最初に、アプリケーションにすべてのシグナル処理を実行させます(より良い意味で)。 SIGINTまたはSIGSEGVがソケットを閉じるかどうかはわかりませんでした。私はいくつかのタイムアウトが発生するまで彼らを開いたままにしておくことを心配していました。私を修正していただきありがとうございます。 – Mike

+0

私は、プロセスが終了時にそれをきれいにするため、許可されたリソースリークに関するいくつかの悪い経験をしました。私は説明するのが難しい奇妙なクラッシュを見てきました。それ以外の理由がない場合は、(コンパイラやスタティックアナライザからの)警告を必要としないようにするには、ビルドのメンテナンスが面倒になります。 –

2

ハンドラで解放しないでください。代わりに、何かを解放する必要があることをプログラムに示します。次に、あなたがプログラムでそれを検出するので、シグナルコンテキストではなく、メインコンテキストから解放することができます。

4

一つの技術(他の人があまりにも存在する):

  1. あなたのプログラムは、メインの処理ループを実行しました。
  2. メイン処理ループでフラグをチェックして、 "実行中"かどうかを確認します。
  3. シグナルハンドラに「keep running」フラグをfalseに設定するだけで、プログラムを終了させることはできません。
  4. 終了する前に、メイン処理ループでメモリのクリーンアップを実行してください。

これは、割り当てと割り当て解除の両方を、既知のシーケンスで呼び出されるコードのブロックに配置する利点があります。それは相互に関連するオブジェクトのウェブを扱うときには神秘的なことであり、同じオブジェクトを混乱させようとする2つの処理フローの間で競合状態になることはありません。

+0

これはライブラリAPIなので、メインループはここには当てはまりません – Mike

+0

私はライブラリではなくアプリケーションをビルドしているので、この解決策は私の問題には完璧です。あなたの答えをありがとう! –

2

ライブラリやアプリケーションを作成していますか?ライブラリを作成している場合は、呼び出し元のアプリケーションと競合するシグナルハンドラをインストールする必要はありません。このようなシグナルを処理したい場合はアプリケーションのビジネスです。そして、(シグナルハンドラのコンテキスト外から)ライブラリへの適切なクリーンアップコールを行います。

もちろん、アプリケーションを作成していても、SIGINTを処理してソケットを閉じてメモリを解放する理由はありません。シグナルを処理する唯一の理由は、が終了しないようにするか、保存していないデータがあるか、または終了する前にクリーンアップする必要がある共有状態(共有メモリやファイルシステムのようなもの)です。メモリを解放するか、独自のプロセスによってのみ使用されるファイル記述子を閉じることは、終了時に実行する必要があるタスクではありません。

+0

いい視点ね。ありがとうございました。 – Mike