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のシグナルハンドラを記述する必要があります。ただし、free()は signal safe function
ではないため、呼び出さないでください。しかし、その変数をfree()する方法は?
ご回答ありがとうございました...
編集:valgrindはまだ到達可能な変数も表示します:
==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.
解決
必要があるとは思わない。 fork()をサポートしているOSは、プロセスの終了方法(終了を含む)に関係なく、プロセスの終了時にmalloc()から割り当てを自動的に解放します。
Cプログラムがプロセスで実行されない環境が存在し、終了時に何を残しておくかについて非常に注意する必要がある環境があります。しかし、これらの環境はPOSIXではなく、fork()をサポートしません。そのため、彼らはシグナルをサポートしていないかもしれません。そのような異常な環境のために書いている場合は、ドキュメントを確認してください...
クリーンなvalgrindレポートを表示する場合は、ハンドラーにイベントを子のイベントループに貼り付け(またはフラグを設定してセマフォなどをポスト)、イベントをクリーンな終了として処理します。また、プログラムが対話型アプリケーションであり、ユーザーのデータをSIGTERMに保存したい場合は、UIフレームワークがまだSIGTERMをイベントに変換していないことを前提にしています。
他のヒント
何かを誤解しているかもしれませんが、確かにSIGTERMの後にプロセス全体が消えて、変数を取りますか?
child()関数を直接呼び出すのではなく、execを使用してメインから子プロセスを開始できます。メインで作業を行うように子プログラムに通知するには、コマンドライン引数を使用します。その後、子プロセスは適切にクリーンアップできます。