今天只看SIGQUEUE函数:声明:其中有部分
http://www.bccn.net/Article/kfyy/vc/jszl/200708/5849.html(编程中国)的摘抄:
3、sigqueue()
#include
#include
int sigqueue(pid_t pid, int sig, const union sigval val)
调用成功返回 0;否则,返回 -1。
sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然也支持前32种),支持信号带有参数,与函数sigaction()配合使用。
sigqueue的第一个参数是指定接收信号的进程ID,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。
|
sigqueue()比kill()传递了更多的附加信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。如果 signo=0,将会执行错误检查,但实际上不发送任何信号,0值信号可用于检查pid的有效性以及当前进程是否有权限向目标进程发送信号。
在调用sigqueue时,sigval_t指定的信息会拷贝到3参数信号处理函数(3参数信号处理函数指的是信号处理函数由sigaction安 装,并设定了sa_sigaction指针,稍后将阐述)的siginfo_t结构中,这样信号处理函数就可以处理这些信息了。由于sigqueue系统 调用支持发送带参数信号,所以比kill()系统调用的功能要灵活和强大得多。
注:sigqueue()发送非实时信号时,第三个参数包含的信息仍然能够传递给信号处理函数; sigqueue()发送非实时信号时,仍然不支持排队,即在信号处理函数执行过程中到来的所有相同信号,都被合并为一个信号。
***************************************************************************************************************************
根据以上对SIGQUEUE函数的讲解,
在调用sigqueue时,sigval_t指定的信息会拷贝到3参数信号处理函数(3参数信号处理函数指的是信号处理函数由sigaction安装,并 设定了sa_sigaction指针,稍后将阐述)的siginfo_t结构中,这样信号处理函数就可以处理这些信息了。由于sigqueue系统调用支 持发送带参数信号
这一部分较难理解:
SIGQUEUE函数的第三个参数是拷贝到SIGQUEUE函数中的,这里有一个3参数SIGQUEUE函数,以下是关于SIGACTION函数此方面的详解:
***********************************************SIGACTION*************************************************************
sigaction()
#include
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
sigaction函数用于改变进程接收到特定信号后的行为。该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个 特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)。第二个参数是指向结构sigaction的一个实例的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理;第三个参数oldact指向的对象用来保存原来对相应信号 的处理,可指定oldact为NULL。如果把第二、第三个参数都设为NULL,那么该函数可用于检查信号的有效性。
第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉
sigaction的结构形态如下:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
参数:
在一些体系上,sa_handler和sa_sigaction共用一个联合体(union),所以不要同时指定两个字段的值。
sa_restorer字段已淘汰,不应该再被使用。
sa_handler字段指定与signum信号关联的行为,可能是SIG_DFL默认行为,SIG_IGN忽略接送到的信号,或者一个信号处理函数指针。这个函数以一个信号编码作为它的唯一参数 。
如果sa_flags中存在SA_SIGINFO标志,那么sa_sigaction将作为signum信号的处理函数。这个函数的第一参数是信号编码,第二参数是siginfo_t结构的指针,第三参数是ucontext_t结构指针(造型为void *)。
sa_mask指定信号处理函数执行的过程中应被阻塞的信号。另外,除了SA_NODEFER标志被指定外,触发信号处理函数执行的那个信号也会被阻塞。
sa_flags指定一系列用于修改信号处理过程行为的标志,由下面的0个或多个标志通过or运算组合而成:
SA_NOCLDSTOP //此标志为on时,假如signum的值是SIGCHLD,则在子进程停止或恢复执行时不会传信号给调用本系统调用的进程。
SA_NOCLDWAIT //此标志为on时,当调用此系统调用的进程之子进程终止时,系统不会建立zombie进程。
SA_RESETHAND //此标志为on时,信号处理函数接收到信号后,会先将对信号处理的方式设为预设方式,而且当函数处理该信号时,后来发生的信号将不会被阻塞。
SA_ONSTACK //如果利用sigaltstack()建立信号专用堆栈,则此标志会把所有信号送往该堆栈。
SA_RESTART //此标志为on时,核心会自动重启信号中断的系统调用,否则返回EINTR错误值。
SA_NODEFER //当此标志为on时,在信号处理函数处置信号的时段中,核心程序不会把这个间隙中产生的信号阻塞。
SA_SIGINFO //此标志为on时,指定信号处理函数需要三个参数,所以应使用sa_sigaction替代sa_handler。
看看头文件:
#define SA_SIGINFO 4 /* Invoke signal-catching function with
57 three arguments instead of one. */
这是头文件中对SA-SIGINFO的描述****************************************************************
好啦,到目前我们捋捋思路:
函数sigaction()的第二个参数指向一个struct sigaction结构的指针,这个结构中有两个函数指针
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
他们都可以作为信号处理函数,使用那一个就要看SA-FLAGS是否标志位SA-SIGINFO,标志啦,就用sa_sigaction指针指向的函数,没有标志,就使用sa_handler指向的函数。
由_sa_handler指定的处理函数只有一个参数,即信号值,所以信号不能传递除信号值之外的任何信息;由_sa_sigaction是指定的信号处 理函数带有三个参数,是为实时信号而设的(当然同样支持非实时信号),它指定一个3参数信号处理函数。第一个参数为信号值,第三个参数没有使用 (posix没有规范使用该参数的标准),第二个参数是指向siginfo_t结构的指针,结构中包含信号携带的数据值,参数所指向的结构如下:
sa_sigaction第二个参数siginfo_t结构的原型如下:
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void * si_ptr; /* POSIX.1b signal */
void * si_addr; /* Memory location which caused fault */
int si_band; /* Band event */
int si_fd; /* File descriptor */
}
看见加黑的结构体没有,这个才是我们今天尧讨论的
他的定义和sigval这个结构定义在一个头文件中
下面是sigval的结构体定义:
/* Type for data associated with a signal. */
33 typedef union sigval
34 {
35 int sival_int;
36 void *sival_ptr;
37 } sigval_t;
采用联合数据结构,说明siginfo_t结构中的si_value要么持有一个4字节的整数值,要么持有一个指针,这就构成了与信号相关的数据。在信号 的处理函数中,包含这样的信号相关数据指针,但没有规定具体如何对这些数据进行操作,操作方法应该由程序开发人员根据具体任务事先约定。
************************************************SIGACTION***************************************************************
现在回到SIGQUEUE函数:
在调用sigqueue时,sigval_t指定的信息会拷贝到3参数信号处理函数(3参数信号处理函数指的是信号处理函数由sigaction安装,并 设定了sa_sigaction指针)的siginfo_t结构中,这样信号处理函数就可以处理这些信息了。由于sigqueue系统调用支 持发送带参数信号,所以比kill()系统调用的功能要灵活和强大得多。
现在就好理解这段话啦!!!