pthread_create から呼び出される次の関数があります。この関数は、いくつかの作業を行い、タイマーを設定し、他の作業を行ってから、タイマーが期限切れになるのを待ってから、ループを再度実行します。ただし、タイマーの最初の実行時に、タイマーの有効期限が切れた後、プログラムが終了し、その理由が完全にはわかりません。無限 while ループから出てはなりません。メイン スレッドはこのスレッドから何もアクセスせず、その逆も同様です (今のところ)。
私の推測では、スレッドで何かが正しくセットアップされていないか、タイマーがハンドラー関数を正しく呼び出していない可能性があります。スレッドから IDLE グローバル変数を変更すると、問題が発生する可能性があります。
シグナルなしでハンドラーを呼び出したいので、SIGEV_THREAD_ID を使用します。とにかく、メインスレッドで SIGUSRx シグナルを使用しています。私がここで始めたことについて何か考えがありますか?何が間違っているのでしょうか?
#ifndef sigev_notify_thread_id
#define sigev_notify_thread_id _sigev_un._tid
#endif
volatile sig_atomic_t IDLE = 0;
timer_t timer_id;
struct sigevent sev;
void handler() {
printf("Timer expired.\n");
IDLE = 0;
}
void *thread_worker() {
struct itimerspec ts;
/* setup the handler for timer event */
memset (&sev, 0, sizeof(struct sigevent));
sev.sigev_notify = SIGEV_THREAD_ID;
sev.sigev_value.sival_ptr = NULL;
sev.sigev_notify_function = handler;
sev.sigev_notify_attributes = NULL;
sev.sigev_signo = SIGRTMIN + 1;
sev.sigev_notify_thread_id = syscall(SYS_gettid);
/* setup "idle" timer */
ts.it_value.tv_sec = 55;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
if (timer_create(0, &sev, &timer_id) == -1) {
printf("timer_create failed: %d: %s\n", errno, strerror(errno));
exit(3);
}
while (1) {
// do work here before timer gets started that takes 5 seconds
while (IDLE); /* wait here until timer_id expires */
/* setup timer */
if (timer_settime(timer_id, 0, &ts, NULL) == -1) {
printf("timer_settime failed: %d\n", errno);
exit(3);
}
IDLE = 1;
// do work here while timer is running but that does not take 10 seconds
}
}