信号处理函数:
sigaction();
int sigaction (int __sig, __const struct sigaction *__restrict __act, struct sigaction *__restrict __oact) __THROW;
|
其中__sig参数为信号,struct sigaction:
struct sigaction
{
/* Signal handler. */
#ifdef __USE_POSIX199309
union
{
/* Used if SA_SIGINFO is not set. */
__sighandler_t sa_handler;
/* Used if SA_SIGINFO is set. */
void (*sa_sigaction) (int, siginfo_t *, void *);
}
__sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction __sigaction_handler.sa_sigaction
#else
__sighandler_t sa_handler;
#endif
/* Additional set of signals to be blocked. */
__sigset_t sa_mask;
/* Special flags. */
int sa_flags;
/* Restore handler. */
void (*sa_restorer) (void);
};
|
当有数据发送时,使用
void (*sa_sigaction) (int, siginfo_t *, void *);
void (*sa_restorer) (void);基本不用了。参数oact为旧的信号sigaction;
typedef struct siginfo
{
int si_signo; /* Signal number. */
int si_errno; /* If non-zero, an errno value associated with this signal, as defined in . */
int si_code; /* Signal code. 引发信号的原因*/
union
{
int _pad[__SI_PAD_SIZE];
/* kill(). */
struct
{
__pid_t si_pid; /* Sending process ID. */
__uid_t si_uid; /* Real user ID of sending process. */
} _kill;
/* POSIX.1b timers. */
struct
{
int si_tid; /* Timer ID. */
int si_overrun; /* Overrun count. */
sigval_t si_sigval; /* Signal value. */
} _timer;
/* POSIX.1b signals. */
struct
{
__pid_t si_pid; /* Sending process ID. */
__uid_t si_uid; /* Real user ID of sending process. */
sigval_t si_sigval; /* Signal value. */
} _rt;
/* SIGCHLD. */
struct
{
__pid_t si_pid; /* Which child. */
__uid_t si_uid; /* Real user ID of sending process. */
int si_status; /* Exit value or signal. */
__clock_t si_utime;
__clock_t si_stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
struct
{
void *si_addr; /* Faulting insn/memory ref. */
} _sigfault;
/* SIGPOLL. */
struct
{
long int si_band; /* Band event for SIGPOLL. */
int si_fd;
} _sigpoll;
} _sifields;
} siginfo_t; /* X/Open requires some more fields with fixed names. */ # define si_pid _sifields._kill.si_pid # define si_uid _sifields._kill.si_uid # define si_timerid _sifields._timer.si_tid # define si_overrun _sifields._timer.si_overrun # define si_status _sifields._sigchld.si_status # define si_utime _sifields._sigchld.si_utime # define si_stime _sifields._sigchld.si_stime # define si_value _sifields._rt.si_sigval # define si_int _sifields._rt.si_sigval.sival_int # define si_ptr _sifields._rt.si_sigval.sival_ptr # define si_addr _sifields._sigfault.si_addr # define si_band _sifields._sigpoll.si_band # define si_fd _sifields._sigpoll.si_fd
|
参数si_code 报告了引发信号的原因。posix为si_code定义了如下值:SI_USER,SI_QUEUE,SI_TIMER,SI_ASYNCIO,SI_MESGQ.值为SI_USR表示信号是由kill,raise,abort函数显式产生的。于是,无法为si_value生成值,因此si_value是未定义的。值为SI_QUEUE说明是函数sigqueue产生的信号。值为SI_TIMER说明是定时器产生的信号。SI_ASYNCIO说明信号异步i/o执行完毕。值为SI_MESGQ说明有消息到达空的消息队列。其它由自定义。
信号发送函数有:
kill();sigqueue();
当有多个信号挂起时,posix保证如果信号被解除了阻塞,那么至少会有一个实例会被传送出去。其它的实例可能会丢失。这时就要用到posix:rts信号排队功能。sigqueue()是对kill()的扩展,它允许对信号进行排队.即使系统对sigqueue产生的信号进行了排队,它可能也不会对kill函数产生的多个与之相同的信号实例排队。
sigqueue函数向ID为pid的进程发送带有值value的信号signo。如果signo为零,就会执行错误检测,但是不会发送信号.如果在安装signo的处理程序时,设置了struct sigaction结构的sa_flags字段的SA_SIGINFO,信号就会被排队,并被送到接收的进程,如果没有设置为SA_SIGINFO,信号至少会被发送一次,但是可能不会被排队。
sigqueue()用于实时信号,对信号进行排队,可以用于传递数据。
int sigqueue (__pid_t __pid, int __sig, __const union sigval __val)
|
/* Type for data associated with a signal. */
typedef union sigval
{
int sival_int; ////整数,
void *sival_ptr; ////指针
} sigval_t;
|
其中sigval_t中的sigval_ptr中可以放下一个指针,因此可以将任意数量的信息传递给信号处理程序。除非信号接收者可以访问到这个发送进程的地址空间,否则传递地址没有任何意义。
阅读(4322) | 评论(0) | 转发(0) |