提供された回答は、これを達成するのに役立つツールがBoostで利用可能であることを示しています。私の最近の提供setitimer()
は、反復タイマー用のPOSIX機能であるの使用方法を示しています。
基本的に次のような変更が必要です。
while (1){
// wait until 200 ms boundary
// get a sample
}
反復タイマーを使用すると、発火した信号はブロックされた信号呼び出しを中断します。だから、あなたは永遠に何かをブロックすることができます。select
そのためにうまくいくでしょう:
while (1){
int select_result = select(0, 0, 0, 0, 0);
assert(select_result < 0 && errno == EINTR);
// get a sample
}
200ミリ秒ごとにインターバルタイマーを設定するには、を使用setitimer()
して、適切なインターバルを渡します。以下のコードでは、間隔を200ミリ秒に設定しています。ここで、最初の間隔は150ミリ秒後に発生します。
struct itimerval it = { { 0, 200000 }, { 0, 150000 } };
if (setitimer(ITIMER_REAL, &it, 0) != 0) {
perror("setitimer");
exit(EXIT_FAILURE);
}
これで、シグナルハンドラーをインストールするだけで、SIGALRM
何も実行されず、コードが完成します。
リンクをたどると、完成した例を見ることができます。
プログラムの実行中に複数のシグナルが発生する可能性がある場合は、中断されたシステムコールに依存するのではなく、SIGALRM
ハンドラーが決定論的な方法でウェイクアップできるものをブロックすることをお勧めします。1つの可能性は、パイプの読み取り端のwhile
ループブロックをオンにすることです。read
シグナルハンドラは、そのパイプの書き込み端に書き込むことができます。
void sigalarm_handler (int)
{
if (write(alarm_pipe[1], "", 1) != 1) {
char msg[] = "write: failed from sigalarm_handler\n";
write(2, msg, sizeof(msg)-1);
abort();
}
}
リンクをたどって、完成した例を確認してください。