分类:
2008-12-08 12:15:00
10.13 sigpending function
#include int sigpending(sigset_t *set); |
Returns: 0 if OK, 1 on error |
用来查看当前进程被block的pending的signal.
下面有一个例子,它使用了若干个函数:
#include "apue.h"
static void sig_quit(int);
int
main(void)
{
sigset_t newmask, oldmask, pendmask;
if (signal(SIGQUIT, sig_quit) ==
SIG_ERR)
err_sys("can't catch
SIGQUIT");
/*
* Block SIGQUIT and save
current signal mask.
*/
sigemptyset(&newmask);
sigaddset(&newmask,
SIGQUIT);
if (sigprocmask(SIG_BLOCK,
&newmask, &oldmask) < 0)
err_sys("SIG_BLOCK
error");
sleep(5); /* SIGQUIT here will remain pending */
if (sigpending(&pendmask)
< 0)
err_sys("sigpending
error");
if (sigismember(&pendmask,
SIGQUIT))
printf("\nSIGQUIT
pending\n");
/*
* Reset signal mask which
unblocks SIGQUIT.
*/
if (sigprocmask(SIG_SETMASK,
&oldmask, NULL) < 0)
err_sys("SIG_SETMASK
error");
printf("SIGQUIT
unblocked\n");
sleep(5); /* SIGQUIT here will terminate with core
file */
exit(0);
}
static void
sig_quit(int signo)
{
printf("caught
SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL) ==
SIG_ERR)
err_sys("can't reset
SIGQUIT");
}
结果:
$ ./a.out
^\ generate signal once (before 5 seconds are up)
SIGQUIT pending after
return from sleep
caught SIGQUIT in
signal handler
SIGQUIT unblocked after
return from sigprocmask
^\Quit(coredump) generate
signal again
$ ./a.out
^\^\^\^\^\^\^\^\^\^\ generate
signal 10 times (before 5 seconds are up)
SIGQUIT pending
caught SIGQUIT signal
is generated only once
SIGQUIT unblocked
^\Quit(coredump) generate
signal again
这个例子中,如果在进程睡眠期间,不知发送一个ctl-backslash信号,那么最终只有一个响应,即该信号不被queue。
这个例子也表现了一个要注意的地方:
如果我们不确定使用者如何使用我们定义的函数,那么在我们这个函数里,如果用sigprocmask(SIG_BLOCK,&newest, &oldest )将一些信号block了,那么在本函数退出之前,一定要使用sigprocmask(SIG_SETMASK, &oldest, 0 )来恢复以前的set,而不能用sigprocmask(SIG_UNBLOCK, &newest, 0),因为,我们不敢确定调用者在调用我们之前是否已经将该信号给block了,所以我们不能简单地将其unblock,而是用SET_MASK来将旧有的mask恢复即可。