への呼び出しの直前にフラグのチェックを追加すれば、Adam Hunt の提案は機能しますselect
。そうしないと、通常の処理がチェックをスキップする可能性が高いため、直前である必要があります。そのため、次に実際のイベントが返さEINTR
れるまで終了が遅れます。select
while (gContinue) {
/*set up some stuff for next select call*/
do {
if (gContinue == 0) break;
nfds = select(...);
} while (nfds == -1 && errno == EINTR);
/*handle select return*/
}
編集:select
Dietrich Epp は、フラグ チェックと への呼び出しによってのみ閉じることができる呼び出しの間に競合状態があることを指摘していますpselect
。pselect
と非常によく似てselect
いますが、主な違いは、最後のパラメーターがマスクとして使用され、ブロックするシグナルを決定することです。pselect
したがって、以下のコード サンプルは、フラグ チェックと呼び出しの間の競合を閉じます。
sigset_t emptyset, blockset, origset;
sigemptyset(&emptyset);
sigemptyset(&blockset);
sigaddset(&blockset, SIGINT);
while (gContinue) {
/*...*/
sigprocmask(SIG_BLOCK, &blockset, &origset);
do {
if (gContinue == 0) break;
nfds = pselect(..., &emptyset);
} while (nfds == -1 && errno == EINTR);
sigprocmask(SIG_SETMASK, &origset, NULL);
/*...*/
};
atexit
もう 1 つの方法は、割り当てられたすべての要素をグローバル データ構造に登録して、インストールしたハンドラーによって解放できるようにすることです。割り当てを解除するコードになった場合は、最初にグローバル データ構造から登録解除します。
m = malloc(sz);
register_allocation(m);
/*...*/
unregister_allocation(m);
free(m);
そして使用atexit
:
void cleanup_allocations () {
/*...*/
}
atexit(cleanup_allocations);