如果你能接受每一個計時器滴答一個新線程的創建,您可以使用SIGEV_THREAD
:
struct sigevent evp;
memset((void *)&evp, 0, sizeof(evp));
evp.sigev_notify = SIGEV_THREAD;
evp.sigev_notify_function = &sig_alrm_handler;
evp.sigev_signo = SIGALRM;
evp.sigev_value.sigval_ptr = (void *)this;
int ret = timer_create(CLOCK_REALTIME, &evp, &_timerId);
這將創建一個新的線程,每刻度。
如果您需要處理在一個特定的線程的信號,更多的工作是必需的:
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;
}
則可能是隻在信號處理器線程選擇性解鎖SIGARLM
,導致它的唯一線索脫身有資格處理該信號,但這可能不是跨系統移植的。
其他版本(包括使用pthread_cond_signal()
)已在this answer中討論過。
對不起,有一個小錯字,我糾正了它。 – Harry
看看[POSIX線程和信號](https://stackoverflow.com/questions/2575106/posix-threads-and-signals)。據我所見,回答也有解決您的問題的方法。 – dhke
@dhke我有一個疑問,如果我在一個單獨的線程本身創建計時器將信號處理程序在該線程內運行? – Harry