を使用した簡単なおもちゃのプログラムを次に示しますvolatile sig_atomic_t
。
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#define UNUSED(x) (void) (x)
volatile sig_atomic_t quit;
void sigusr1_handler(int sig)
{
UNUSED(sig);
write(1, "handler\n", 8);
quit = 1;
}
int main()
{
struct sigaction sa;
sa.sa_handler = sigusr1_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
quit = 0;
while (!quit)
;
printf("Exiting ...\n");
return 0;
}
この特定のプログラムの変数にvolatile sig_atomic_t
必要な理由はわかっていると思います。quit
- がない
volatile
と、コンパイラはwhile (!quit) ;
無限ループに最適化する可能性があります。ループの変更が見つからないため、常に残っquit
ていると見なされます。quit
0
- への更新
quit
または読み取りはquit
、単一のマシン命令で発生する必要があります。の更新または読み取りに複数のマシン命令が必要quit
な場合、更新の進行中にシグナル ハンドラーが呼び出されると、シグナル ハンドラーの読み取りで の値が矛盾する可能性がありますquit
。
私はこれまでのところ正しいですか?そうでない場合は、答えを修正してください。
sig_atomic_t
ここで、シグナル処理のコンテキストで必要な場合の一般化されたルールを学びたいと思います。Jonathan Leffler はコメントで、一般化するのは簡単ではないと説明しました。
sig_atomic_t
C標準の観点から、変数を定義する必要がある既知のシナリオのリストを提供できますか? 網羅的なリストである必要はありません。これは、経験の浅い開発者がシグナル処理コードを含む C ソフトウェアを作成する際に参照できるリストになる可能性があります。