我从pthread_create调用了以下函数。这个函数做了一些工作,设置了一个计时器,做了一些其他的工作,然后在再次循环之前等待计时器到期。但是,在计时器第一次运行时,程序到期后程序退出,我不完全确定原因。它永远不应该离开无限循环。主线程不从该线程访问任何内容,反之亦然(现在)。
我的猜测是我可能没有正确设置线程,或者计时器没有正确调用处理函数。也许从线程中更改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
}
}
答案 0 :(得分:1)
据我所知,你还没有为SIGUSR1
安装一个信号处理程序,因此默认操作会在它被采取行动时终止进程。
无论如何,整件事让我感到非常糟糕:
在等待计时器到期时,while循环将为您提供100%的CPU负载。
这不是您使用SIGEV_THREAD_ID
的方式,实际上SIGEV_THREAD_ID
实际上并未设置为可供应用程序使用。而是由libc在内部用于实现SIGEV_THREAD
。
你真的不想使用信号。他们很乱。
如果您有线程,为什么不在循环中调用clock_nanosleep
?定时器主要用于不能做到这一点,例如当你不能使用线程时。