我想使用Linux POSIX定时器API在系统中实现一个定时器处理模块。用户可以启动计时器,并进行回调。回调的调用将从线程(而不是从信号处理程序)完成。
我想用SIGEV_SIGNAL设置timer_create(),线程使用sigwaitinfo()等待信号(信号arg将给出调用所需回调的timerId)
信号在linux内核中是如何路由的?我需要指定它们被发送到哪个线程吗?
默认情况下,信号可以传递到任何线程,不应该假设是哪个线程。然而,Posix线程可以让您对此进行一些控制。您通常会将SIGALRM与计时器结合使用,但我有一个SIGHUP的示例,所以我将在这里展示它来演示工作流。
当您的应用程序启动时,主线程设置要忽略的信号的全局处理:
int n;
sigset_t set;
struct sigaction disp;
bzero(&disp, sizeof(disp));
disp.sa_handler = SIG_IGN;
if (sigaction(SIGHUP, &disp, NULL) < 0) {
syslog(LOG_CRIT, "sigaction_main: %m");
_exit(1);
}
接下来,您要确保新派生的线程将继承的掩码也被阻止了以下信号:
sigemptyset(&set);
sigaddset(&set, SIGHUP);
if ( (errno = pthread_sigmask(SIG_BLOCK, &set, NULL)) != 0) {
syslog(LOG_CRIT, "sigmask_main: %m");
_exit(1);
}
此时,您生成了不应被信号(HUP)中断的所有线程。完成这一切之后,主线程进入信号等待和处理的专用模式:
for (; ;) {
if ( (errno = sigwait(&set, &n)) != 0) {
syslog(LOG_CRIT, "sigwait_main: %m");
_exit(1);
}
if (n == SIGHUP) {
/* do the errands */
}
}