2009-05-02 8 views
0

は、私は、プロセスをフォークした場合、すべての変数があまりにもクローニングされ、このダイナミックに割り当てられた変数をSIGTERMで解放するには?

... HEADERS ... 

int *var; 

void child() { 
    ... //some work 
    free(var); 
    exit(EXIT_SUCCESSFUL); 
} 

int main(void) { 
    ... 
    //allocate variable 
    var = (int *) malloc(N*sizeof(int)); 
    ... //work with var 

    for(int i; i<PROC_COUNT; i++) { 
    pid_t child = fork(); 
    if(pid == 0) { 
     child(); //main function of new proces 
     break; 
    } 
    elseif(pid < 0) { 
     //there is enormous problem -> kill every proces 
     kill(0, SIGTERM); 
     waitpid(0, NULL, 0); //wait for children 
     free(var); 
     exit(EXIT_FAILURE); 
    } 

    } 
    free(var); 
    return EXIT_SUCCESS; 
} 

のようなコードを何かに取り組んでいます。通常、varのすべてのコピーが解放されます。

fork()でエラーが発生した場合は、作成したすべてのプロセスにシグナルSIGTERMを送信します。そして、私はSIGTERMのシグナルハンドラを書く必要があります。これは、varを解放してアプリケーションを終了させます。しかし、free()はsignal safe functionではありません - 私はそれを呼び出すべきではありません。しかし、その変数を解放する方法は?

あなたの答えに感謝をたくさん...

EDIT:valgrindのもまだreacheable変数を示しています

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1) 
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks. 
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated. 
==5928== For counts of detected errors, rerun with: -v 
==5928== searching for pointers to 1 not-freed blocks. 
==5928== checked 49,164 bytes. 
+0

Enourmouse?それはある種の大きな先史時代のげっ歯類ですか? :-) – JesperE

+0

私はあなたのご容赦を願います、それはスロバキアで少し遅れているので、私は間違っていました。通知ありがとう。 – izidor

答えて

4

私はあなたが必要と疑う。 fork()をサポートするすべてのOSは、プロセスの終了時(終了を含む)にかかわらず、プロセスが終了したときに自動的にmalloc()から割り当てを解放します。

Cプログラムがプロセス内で実行されない環境があります。また、終了時に何が残っているのか非常に注意する必要がある環境があります。しかし、これらの環境はPOSIXではなく、fork()をサポートしません。彼らはシグナルをサポートしていないかもしれません。そのような異常な環境で書いている場合は、ドキュメントをチェックしてください。

きれいなvalgrindレポートを表示したい場合は、ハンドラに子イベントループにイベントをスティックすることができますセマフォーを送信するなど)、イベントをクリーンな出口として処理します。これは、プログラムがインタラクティブアプリケーションで、UIフレームワークがまだSIGTERMをイベントに変換していなかったと仮定して、SIGTERMにユーザのデータを保存したい場合にも実行します。

+0

なぜvalgrindがまだ到達可能なメモリを示しているのですか? (たぶんあなたは正しいと思いますし、valgrindで示されたごみは間違った種類のvalgrind meassurmentによって作られています) – izidor

+0

valgrindは、あなたが終了する前にメモリを解放していないことを警告しようとしています。その後もすぐにOSによって解放されます。通常、valgrindからの報告はあなたのプログラムがメモリを失っている可能性があると疑わせるでしょう。しかし、SIGTERMの終了の場合は、これを無視することができます。通常のクリーンアップを行っていないことを知っているので、「メモリリーク」という偽の主張が予想されます。 –

+0

よろしくお願いいたします。 問題のあることを修正できるかどうか疑問に思っていました。 ありがとうございました! – izidor

0

私は何かを誤解することができる、しかし確実にSIGTERM後に全体のプロセスが表示されなくなります、あなたの変数をそれに連れて行く?

0

execを使用して、child()関数を直接呼び出すのではなく、メインから子プロセスを開始することができます。コマンドライン引数を使用して、メインプログラムでメインプログラムを実行するように子プログラムに通知します。その後、子プロセスは適切にクリーンアップできます。

関連する問題