考虑我设置的这个例子来说明这一点。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this prevent SIGALRM from interrupting main? */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this make pause() return in this thread? */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
这里是输出,用gcc编译:
Main thread done.
Handler handled.
消息之间大约有一秒半。
为什么我的第二个帖子pause
永远不会回来?
答案 0 :(得分:2)
我猜错误在pthread_sigmask
的使用中。使用SIG_BLOCK
和SIG_UNBLOCK
代替SIG_SETMASK
,程序的行为与您期望的一样。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
/* This prevent SIGALARM interrupring the main */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
/* This make the pause() return on SIGALARM */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
该程序提供以下输出:
$ ./test
Main thread done.
Handler handled.
Off thread's pause returned.
特别是:
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
你正在取消主线程中的所有信号。同时,用:
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
您只在子线程上阻止SIGALARM
。这可能与你想做的事情相反。
请注意,使用SIG_SETMASK
指定阻止信号集。