柳州免费做网站的公司,网页设计用到的软件,制作网页教程需要什么工具,国内产品网站1688一、信号从发送到被处理经历的过程
1、常见概念
(1) 信号阻塞
阻塞#xff0c;即被进程拉黑#xff0c;信号被发送后#xff0c;分为两种情况#xff0c;一种是被阻塞了#xff08;被拉黑了#xff09;#xff0c;一种是没有被阻塞。
(2) 信号未决
在信号被进程处理…一、信号从发送到被处理经历的过程
1、常见概念
(1) 信号阻塞
阻塞即被进程拉黑信号被发送后分为两种情况一种是被阻塞了被拉黑了一种是没有被阻塞。
(2) 信号未决
在信号被进程处理之前的过程都可以称为信号未决
(3) 信号递达
信号被进程处理我们称为信号递达
(4) 信号忽略
进程收到信号后直接忽略不进行处理是否还有默认处理呢忽略中断信号验证是否会中断
(5) 阻塞信号集
指一个进程中当前阻塞而不能够递送给该进程的信号集
(6) 未决信号集
指当前进程未处理的信号集收到阻塞的信号未决信号集该信号位会置1解除阻塞后会置0。
2、信号保存的方式内核级 block表对应的信号是否被阻塞0表示不阻塞1表示阻塞
pending表信号是否被收到0表示未收到该信号1表示收到该信号
handler表表示对应信号的处理方式函数存放的是函数的地址函数指针 3、信号从发送到被处理 第一列表示第 N 号信号以第二行为例阻塞信号为 1 说明该信号被阻塞了相当于在进程的黑名单里后面的未决信号是0还是1都无所谓了
以第四行为例阻塞信号为0该信号没有被阻塞未决信号为1说明收到这个信号了对应的处理方式是 sighandler函数那就会执行该函数
注意
SIG_DFL(signal default)信号默认处理方式
SIG_IGN(signal ignore)忽略信号
总结
先看block如果block为1即信号被拉黑是否收到信号都不重要了
如果block不为1那就再看pending是否为1即是否收到信号 二、信号集操作信号保存
阻塞信号其实就是要修改block表但是要怎么修改呢如果只是传递单个信号或许可以直接以某种方式告诉OS我希望阻塞哪个信号但是如果要修改多个信号呢OS给出了一种方案来解决传递单个或者多个信号那就是直接传递位图
收到一个信号之后执行信号处理函数在执行信号处理函数的过程中如果又来了一个相同的信号那么这个信号将会被阻塞直到信号处理函数执行完之后再响应被阻塞的信号注意如果信号被阻塞期间又收到了该信号那么多个信号的处理会被合并为1次。
信号集就是用来记录当前收到了哪个信号会把当前信号的标志位置成“正在处理”如果此时再收到该信号那么信号就阻塞等待使用数据类型sigset_t表示信号集在Linux中该类型是一个32位无符号整数这是因为在Linux中定义了32种信号每一个信号用32位无符号整型变量中的一位来标志如果该位置为1那么表示正在处理该信号如果置为0表示可以处理该信号。
未决信号集保存当前为处理的信号集。
信号屏蔽字又叫阻塞信号集是指一个进程中当前阻塞而不能够递送给该进程的信号集。每个进程都有一个信号屏蔽字它规定了当前要阻塞递达到该进程的信号集
1、特定的数据类型sigset_t
既然要传递位图要用什么来表示位图呢第一想法是int/uint32_t不同的操作系统实现位图的方式可能有所不同Linux操作系统不光给我们提供了 保存位图的数据类型 sigset_t还有对应的函数来操作位图下面说
——》sigset_t 可以看作是一个信号集保存着1~31号信号的状态0表示没收到1表示收到了
2、操作信号集的函数
(1) sigemptyset函数清空信号集全部位置置0。GUN C库中的非标准函数
int sigemptyset ( sigset_t *set);
成功返回0失败返回-1
(2) sigfillset函数初始化信号集全部置1。GUN C库中的非标准函数
int sigfillset( sigset_t *set);
成功返回0失败返回-1
(3) sigaddset函数向信号集中添加一个信号将对应信号置1。标准函数
假设一开始所有的比特位都是 00000 0000 ...如果我们希望把第二个信号阻塞那么就需要先把信号集的第二个比特位设置为10100 0000....然后再传给信号阻塞函数
int sigaddset( sigset_t *set, int signum); 第一个参数是传入信号集的地址第二个参数是要把哪个位置信号设置成1成功返回0失败返回-1
(4) sigdelset函数从信号集中删除一个信号将对应信号置0。标准函数
假设前面已经阻塞了2号信号这个时候的比特位显示为0100 0000....现在我们不希望阻塞2号信号那么需要把第二个位置信号设置为 0 0000 0000....
int sigdelset( sigset_t *set, int signum); 第一个参数是传入信号集的地址第二个参数是要把哪个位置信号设置成1成功返回0失败返回-1
(5) sigismember函数判断某个信号是否为信号集的成员判断是否在信号集中。标准函数
如果对应位置信号的比特位为1说明在信号集中如果为0说明不在信号集中
int sigismember( sigset_t *set, int signum);
成功返回1失败返回0 如果使用sigemptyset()初始化信号集信号集的所有位置0此时可以接收到所有的信号
如果使用sigfillset()初始化信号集信号集的所有位置1此时屏蔽所有信号当然SIGKILL和SIGQUIT信号是不能屏蔽的
sigaddset()和sigdelset()的意义在于指定屏蔽某信号或者接收某信号 int sigprocmask (int how, const sigset_t *restrict set, sigset_t *restrict oset);
how取值有下列三个
SIG_BLOCK set中包含的是希望阻塞的附加信号合并set中的信号集
SIG_UNBLOCKset中包含的是希望解除阻塞的信号删除set中的信号集
SIG_SETMASKset中包含的是现有屏蔽字的代替值替换set中的信号集
若oset是非空指针则返回进程的当前信号屏蔽字。
若set为空则进程信号屏蔽字不变how值无意义。
另外注意一点不可以阻塞SIGKILL和SIGSTOP信号。
注意调用该接口将信号设置为非阻塞时若该信号已经是阻塞状态则在该函数返回前马上会发给该线程 int sigpending ( sigset_t *set );
此函数通过set返回当前检查未决的信号集。其中的各个信号对于调用进程是阻塞的而不能递送因而也一定是当前未决的。 signal 函数的使用方法简单但并不属于 POSIX 标准在各类 UNIX 平台上的实现不尽相同因此其用途受到了一定的限制。而 POSIX 标准定义的信号处理接口是 sigaction 函数。
int sigaction ( int signum, const struct sigaction *act, struct sigaction *oldact ) ;
signum要操作的信号。
act要设置的对信号的新处理方式。
oldact原来对信号的处理方式。
返回值0 表示成功-1 表示有错误发生。
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 是一个函数指针其含义与 signal 函数中的信号处理函数类似。成员sa_sigaction 则是另一个信号处理函数它有三个参数可以获得关于信号的更详细的信息。当 sa_flags 成员的值包含了 SA_SIGINFO 标志时系统将使用 sa_sigaction 函数作为信号处理函数否则使用 sa_handler 作为信号处理函数。在某些系统中成员 sa_handler 与 sa_sigaction 被放在联合体中因此使用时不要同时设置。
sa_mask 用来指定在信号处理函数执行期间需要被屏蔽的信号特别是当某个信号被处理时它自身会被自动放入进程的信号掩码因此在信号处理函数执行期间这个信号不会再度发生。
sa_flags 用于指定信号处理的行为它可以是一下值的“按位或”组合。 ◆ SA_RESTART如果信号中断了进程的某个系统调用则系统自动启动该系统调用 ◆ SA_NOCLDSTOP使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。 ◆ SA_NOCLDWAIT使父进程在它的子进程退出时不会收到 SIGCHLD 信号这时子进程如果退出也不会成为僵尸进程。 ◆ SA_NODEFER一般情况下当信号处理函数运行时内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记那么在该信号处理函数运行时内核将不会阻塞该信号。 ◆ SA_RESETHAND当调用信号处理函数时将信号的处理函数重置为缺省值SIG_DFL。 ◆ SA_SIGINFO使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。
re_restorer 是一个已经废弃的数据域不要使用。 可重入函数
一个函数被重入表示这个函数没有执行完成由于外部因素或内部调用又一次进入该函数执行。一个函数要被重入只有两种情况
1、多线程同时执行这个函数
2、函数自身可能经过多层调用之后调用自身
一个函数可重入表示这个函数被重入后不会产生任何不良后果。要成人可重入函数必须有以下特定
1、不使用任何局部静态或全局的非const变量
2、不返回任何局部静态或全局的非const变量的指针
3、依赖调用方提供参数
4、不依赖任何单个资源的锁
5、不调用任何不可重入的函数