1. 概念:
信号屏蔽字就是进程中被阻塞的信号集, 这些信号不能发送给该进程, 它们在该进程中被"屏蔽"了. 后面我们会提到,
实际上它们是被阻塞了.
2. 信号屏蔽函数:
#include
int sigprocmask(int how, const sigset_t *restrict set, sigset_t
*restrict oset);
成功则返回0, 出错则返回-1.
sigprocmask函数有3个参数:
how: 修改信号屏蔽字的方式.
set: 把这个信号集设为新的当前信号屏蔽字. 如果为NULL则不改变.
oset: 保存进程旧的信号屏蔽字. 如果为NULL则不保存.
参数中的how可以取3个值:
sigprocmask中的how参数 how 说明
SIG_BLOCK 修改后, 该进程新的信号屏蔽字是其当前屏蔽字和set指向的信号集的并集.
SIG_UNBLOCK 修改后, 该进程新的信号屏蔽字是其当前屏蔽字和set指向的信号集的补集的交集.
SIG_SETMASK 修改后, 该进程新的信号屏蔽字将被set指向的信号集的值代替
另外要说的是, sigprocmask只为单线程定义的,
在多线程中要使用pthread_sigmask.
3. 未处理的信号:
在调用信号屏蔽的相关函数后, 被屏蔽的信号对于调用进程是阻塞的, 不能发送给调用进程, 因此是未决的. 取得这些阻塞的信号集,
可以通过调用sigpending函数.
#include
int sigpending(sigset_t *set);
成功则返回0, 出错则返回-1.
4. 实例:
下面通过一个简单的实例来说明这篇文章中所讲到的两个函数.
#include
#include
#include
#include
static void sig_quit(int signo)
{
printf("SIGQUIT is caught ");
}
int main()
{
sigset_t
new, old, pend;
if
(signal(SIGQUIT, sig_quit) == SIG_ERR)
{
perror("signal");
exit(1);
}
if
(sigemptyset(&new) < 0)
perror("sigemptyset");
if
(sigaddset(&new, SIGQUIT) < 0)
perror("sigaddset");
if
(sigprocmask(SIG_SETMASK, &new,
&old) < 0)
{
perror("sigprocmask");
exit(1);
}
printf("SIGQUIT is blocked ");
printf("Now
try Ctrl ");
sleep(5);
if
(sigpending(&pend) < 0)
perror("sigpending");
if
(sigismember(&pend, SIGQUIT))
printf("SIGQUIT pending ");
if
(sigprocmask(SIG_SETMASK, &old, NULL)
< 0)
{
perror("sigprocmask");
exit(1);
}
printf("
SIGQUIT unblocked ");
printf("Now
try Ctrl ");
sleep(5);
return
0;
}
这个程序在开始的时候用sigprocmask屏蔽了SIGQUIT(ctrl+触发),
在5秒内触发的该信号将可以从sigpending中获得; 然后程序把SIGQUIT解除屏蔽(恢复以前的屏蔽字),
此时再触发该信号将调用sig_quit信号处理函数.
附:signal.h
#ifndef _SIGNAL_H
#if !defined __need_sig_atomic_t
&& !defined __need_sigset_t
# define _SIGNAL_H
#endif
#include
__BEGIN_DECLS
#include
#if defined __need_sig_atomic_t || defined _SIGNAL_H
# ifndef __sig_atomic_t_defined
# define __sig_atomic_t_defined
__BEGIN_NAMESPACE_STD
typedef __sig_atomic_t sig_atomic_t;
__END_NAMESPACE_STD
# endif
# undef __need_sig_atomic_t
#endif
#if defined __need_sigset_t || (defined _SIGNAL_H
&& defined __USE_POSIX)
# ifndef __sigset_t_defined
# define __sigset_t_defined
typedef __sigset_t sigset_t;
# endif
# undef __need_sigset_t
#endif
#ifdef _SIGNAL_H
#include
#include
#ifdef __USE_XOPEN
# ifndef __pid_t_defined
typedef __pid_t pid_t;
# define __pid_t_defined
# endif
# ifndef __uid_t_defined
typedef __uid_t uid_t;
# define __uid_t_defined
# endif
#endif
typedef void (*__sighandler_t) (int);
extern __sighandler_t __sysv_signal (int __sig, __sighandler_t
__handler)
__THROW;
#ifdef __USE_GNU
extern __sighandler_t sysv_signal (int __sig, __sighandler_t
__handler)
__THROW;
#endif
__BEGIN_NAMESPACE_STD
#ifdef __USE_BSD
extern __sighandler_t signal (int __sig, __sighandler_t __handler)
__THROW;
#else
# ifdef __REDIRECT
extern __sighandler_t __REDIRECT (signal,
(int __sig,
__sighandler_t __handler) __THROW,
__sysv_signal);
# else
# define signal __sysv_signal
# endif
#endif
__END_NAMESPACE_STD
#ifdef __USE_XOPEN
extern __sighandler_t bsd_signal (int __sig, __sighandler_t
__handler) __THROW;
#endif
#ifdef __USE_POSIX
extern int kill (__pid_t __pid, int __sig) __THROW;
#endif
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int killpg (__pid_t __pgrp, int __sig) __THROW;
#endif
__BEGIN_NAMESPACE_STD
extern int raise (int __sig) __THROW;
__END_NAMESPACE_STD
#ifdef __USE_SVID
extern __sighandler_t ssignal (int __sig, __sighandler_t __handler)
__THROW;
extern int gsignal (int __sig) __THROW;
#endif
#ifdef __USE_MISC
extern void psignal (int __sig, __const char *__s) __THROW;
#endif
extern int __sigpause (int __sig_or_mask, int __is_sig)
__THROW;
#ifdef __USE_BSD
extern int sigpause (int __mask) __THROW;
# define sigpause(mask) __sigpause ((mask), 0)
#else
# ifdef __USE_XOPEN
# ifdef __GNUC__
extern int sigpause (int __sig) __THROW __asm__
("__xpg_sigpause");
# endif
# define sigpause(sig) __sigpause ((sig),
1)
# endif
#endif
#ifdef __USE_BSD
# define sigmask(sig) __sigmask(sig)
extern int sigblock (int __mask) __THROW;
extern int sigsetmask (int __mask) __THROW;
extern int siggetmask (void) __THROW;
#endif
#ifdef __USE_MISC
# define NSIG _NSIG
#endif
#ifdef __USE_GNU
typedef __sighandler_t sighandler_t;
#endif
#ifdef __USE_BSD
typedef __sighandler_t sig_t;
#endif
#ifdef __USE_POSIX
# ifdef __USE_POSIX199309
# define __need_timespec
# include
# include
# endif
extern int sigemptyset (sigset_t *__set) __THROW;
extern int sigfillset (sigset_t *__set) __THROW;
extern int sigaddset (sigset_t *__set, int __signo) __THROW;
extern int sigdelset (sigset_t *__set, int __signo) __THROW;
extern int sigismember (__const sigset_t *__set, int __signo)
__THROW;
# ifdef __USE_GNU
extern int sigisemptyset (__const sigset_t *__set) __THROW;
extern int sigandset (sigset_t *__set, __const sigset_t
*__left,
__const sigset_t *__right) __THROW;
extern int sigorset (sigset_t *__set, __const sigset_t
*__left,
__const sigset_t *__right) __THROW;
# endif
# include
extern int sigprocmask (int __how, __const sigset_t *__restrict
__set,
sigset_t
*__restrict __oset) __THROW;
extern int sigsuspend (__const sigset_t *__set) __THROW;
extern int sigaction (int __sig, __const struct sigaction
*__restrict __act,
struct sigaction *__restrict __oact) __THROW;
extern int sigpending (sigset_t *__set) __THROW;
extern int sigwait (__const sigset_t *__restrict __set, int
*__restrict __sig)
__THROW;
# ifdef __USE_POSIX199309
extern int sigwaitinfo (__const sigset_t *__restrict __set,
siginfo_t
*__restrict __info) __THROW;
extern int sigtimedwait (__const sigset_t *__restrict __set,
siginfo_t
*__restrict __info,
__const
struct timespec *__restrict __timeout)
__THROW;
extern int sigqueue (__pid_t __pid, int __sig, __const union sigval
__val)
__THROW;
# endif
#endif
#ifdef __USE_BSD
extern __const char *__const _sys_siglist[_NSIG];
extern __const char *__const sys_siglist[_NSIG];
struct sigvec
{
__sighandler_t sv_handler; int
sv_mask;
int
sv_flags; # define sv_onstack sv_flags
};
# define SV_ONSTACK (1
<< 0)
# define SV_INTERRUPT (1
<< 1)
# define SV_RESETHAND (1
<< 2)
extern int sigvec (int __sig, __const struct sigvec *__vec,
struct sigvec *__ovec) __THROW;
# include
extern int sigreturn (struct sigcontext *__scp) __THROW;
#endif
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int siginterrupt (int __sig, int __interrupt) __THROW;
# include
# ifdef __USE_XOPEN
# include
# endif
extern int sigstack (struct sigstack *__ss, struct sigstack *__oss)
__THROW;
extern int sigaltstack (__const struct sigaltstack *__restrict
__ss,
struct
sigaltstack *__restrict __oss) __THROW;
#endif
#ifdef __USE_UNIX98
extern int sighold (int __sig) __THROW;
extern int sigrelse (int __sig) __THROW;
extern int sigignore (int __sig) __THROW;
extern __sighandler_t sigset (int __sig, __sighandler_t __disp)
__THROW;
#endif
#if defined __USE_POSIX199506 || defined __USE_UNIX98
# include
# include
#endif
extern int __libc_current_sigrtmin (void) __THROW;
extern int __libc_current_sigrtmax (void) __THROW;
#endif
__END_DECLS
#endif