我正在开发一个应用程序,其中我使用timer_create函数创建了一个计时器,该函数在到期时向线程发送信号。到目前为止,我能够实现向特定线程传递定时器信号。我现在面临的问题是,如果有另一个计时器,如何将信号传递到另一个单独的线程(基本上第一个定时器信号到线程A,第二个定时器信号到线程B)。这是我到目前为止所写的内容
static void *
sig_threadproc(void *thrarg)
{
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
/* endless loop to wait for and handle a signal repeatedly */
for (;;) {
int sig;
int error;
error = sigwait(&sigset, &sig);
if (error == 0) {
assert(sig == SIGALRM);
printf("got SIGALRM\n");
} else {
perror("sigwait");
}
}
return NULL;
}
static void
sig_alrm_handler(int signo)
{
/**
* dummy signal handler,
* the signal is actually handled in sig_threadproc()
**/
}
int
main(int argc, char *argv[])
{
sigset_t sigset;
struct sigaction sa;
pthread_t sig_thread;
struct itimerspec tspec;
timer_t timer_id;
/* mask SIGALRM in all threads by default */
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
sigprocmask(SIG_BLOCK, &sigset, NULL);
/* we need a signal handler.
* The default is to call abort() and
* setting SIG_IGN might cause the signal
* to not be delivered at all.
**/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sig_alrm_handler;
sigaction(SIGALRM, &sa, NULL);
/* create SIGALRM looper thread */
pthread_create(&sig_thread, NULL, sig_threadproc, NULL);
/* setup timer */
tspec.it_interval.tv_sec = 1;
tspec.it_interval.tv_nsec = 0;
tspec.it_value.tv_sec = 1;
tspec.it_value.tv_nsec = 0;
timer_create(CLOCK_REALTIME, NULL, &timer_id);
timer_settime(timer_id, 0, &tspec, NULL);
/**
* this might return early if usleep() is interrupted (by a signal)
* It should not happen, since SIGALRM is blocked on the
* main thread
**/
usleep(10000000);
return 0;
}
答案 0 :(得分:0)
不要将SIGALRM
用于实时计时器,而是使用SIGRTMIN
。因此,您将创建两个计时器,对于第一个计时器,将sigev_signo
参数的sevp
成员设置为SIGRTMIN + 0
,并将第二个segev_signo
设置为SIGRTMIN + 1
{1}}。这意味着当第一个计时器触发时,您的进程将收到SIGRTMIN
信号,当第二个计时器触发时,您将收到SIGRTMIN + 1
。
然后在程序的2个线程中调用pthread_sigmask
,在线程B中屏蔽信号SIGRTMIN
,并在线程A中屏蔽SIGRTMIN + 1
。
结果,您的线程A将仅在第一个计时器触发时通知,而线程B将从第二个计时器获得通知。