永州公司做网站,wordpress如何添加注册按钮,如何做一个漂亮的网页,wordpress临时关闭页面转载#xff1a;信号集操作函数#xff0c;信号阻塞与未决 一#xff0c;信号集及相关操作函数 信号集被定义为一种数据类型#xff1a; typedef struct { unsigned long sig[_NSIG_WORDS]#xff1b; } sigset_t 信号集用来描述信号的集合#xff0c;每个信号占用一位信号集操作函数信号阻塞与未决 一信号集及相关操作函数 信号集被定义为一种数据类型 typedef struct { unsigned long sig[_NSIG_WORDS] } sigset_t 信号集用来描述信号的集合每个信号占用一位64位。Linux所支持的所有信号可以全部或部分的出现在信号集中主要与信号阻塞相关函数配合使用。下面是为信号集操作定义的相关函数 #include signal.h int sigemptyset(sigset_t *set) int sigfillset(sigset_t *set) int sigaddset(sigset_t *set, int signum) int sigdelset(sigset_t *set, int signum) int sigismember(const sigset_t *set, int signum) sigemptyset(sigset_t *set)初始化由set指定的信号集信号集里面的所有信号被清空相当于64为置0 sigfillset(sigset_t *set)调用该函数后set指向的信号集中将包含linux支持的64种信号相当于64为都置1 sigaddset(sigset_t *set, int signum)在set指向的信号集中加入signum信号相当于将给定信号所对应的位置1 sigdelset(sigset_t *set, int signum)在set指向的信号集中删除signum信号相当于将给定信号所对应的位置0 sigismember(const sigset_t *set, int signum)判定信号signum是否在set指向的信号集中相当于检查给定信号所对应的位是0还是1。 示例程序 #include stdio.h
#include unistd.h
#include stdlib.h
#include signal.h
#include sys/types.h
void print_sigset(sigset_t *set);
int main(void)
{sigset_t myset;sigemptyset(myset);sigaddset(myset,SIGINT);sigaddset(myset,SIGQUIT);sigaddset(myset,SIGUSR1);sigaddset(myset,SIGRTMIN);print_sigset(myset);return 0;}
void print_sigset(sigset_t *set)
{int i;for(i 1; i NSIG; i){if(sigismember(set,i))printf(1);elseprintf(0);}putchar(\n);
} 结果 可以看到添加信号的相应位置1. 二信号阻塞与未决 man帮助说明 Signal mask and pending signals A signal may be blocked, which means that it will not be delivereduntil it is later unblocked. Between the time when it is generatedand when it is delivered a signal is said to be pending. Each thread in a process has an independent signal mask, whichindicates the set of signals that the thread is currently blocking.A thread can manipulate its signal mask using pthread_sigmask(3). Ina traditional single-threaded application, sigprocmask(2) can be usedto manipulate the signal mask.
执行信号的处理动作称为信号递达Delivery信号从产生到递达之间的状态称为信号未决Pending。进程可以选择阻塞Block某个信号。被阻塞的信号产生时将保持在未决状态直到进程解除对此信号的阻塞才执行递达的动作。注意阻塞和忽略是不同的只要信号被阻塞就不会递达而忽略是在递达之后可选的一种处理动作。每个进程都有一个用来描述哪些信号递送到进程时将被阻塞的信号集该信号集中的所有信号在递送到进程后都将被阻塞。
信号在内核中的表示可以看作是这样的 看图说话
block集阻塞集、屏蔽集一个进程所要屏蔽的信号在对应要屏蔽的信号位置1
pending集未决信号集如果某个信号在进程的阻塞集中则也在未决集中对应位置1表示该信号不能被递达不会被处理
handler信号处理函数集表示每个信号所对应的信号处理函数当信号不在未决集中时将被调用 以下是与信号阻塞及未决相关的函数操作 #include signal.h int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)) int sigpending(sigset_t *set)); int sigsuspend(const sigset_t *mask)) sigprocmask()函数能够根据参数how来实现对信号集的操作操作主要有三种
SIG_BLOCK 在进程当前阻塞信号集中添加set指向信号集中的信号相当于maskmask|setSIG_UNBLOCK 如果进程阻塞信号集中包含set指向信号集中的信号则解除对该信号的阻塞相当于maskmask|~setSIG_SETMASK 更新进程阻塞信号集为set指向的信号集相当于maskset sigpending(sigset_t *set))获得当前已递送到进程却被阻塞的所有信号在set指向的信号集中返回结果。 sigsuspend(const sigset_t *mask))用于在接收到某个信号之前, 临时用mask替换进程的信号掩码, 并暂停进程执行直到收到信号为止。 sigsuspend 返回后将恢复调用之前的信号掩码。信号处理函数完成后进程将继续执行。该系统调用始终返回-1并将errno设置为EINTR。 示例程序 #include unistd.h
#include sys/stat.h
#include sys/wait.h
#include sys/types.h
#include fcntl.h#include stdlib.h
#include stdio.h
#include errno.h
#include string.h
#include signal.h#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \} while(0)void handler(int sig);
void printsigset(sigset_t *set)
{int i;for (i1; iNSIG; i){if (sigismember(set, i))putchar(1);elseputchar(0);}printf(\n);
}int main(int argc, char *argv[])
{sigset_t pset;sigset_t bset;sigemptyset(bset);sigaddset(bset, SIGINT);if (signal(SIGINT, handler) SIG_ERR)ERR_EXIT(signal error);if (signal(SIGQUIT, handler) SIG_ERR)ERR_EXIT(signal error);sigprocmask(SIG_BLOCK, bset, NULL);//将信号加入进程阻塞集中for (;;){sigpending(pset);printsigset(pset);sleep(1);}return 0;
}void handler(int sig)
{if (sig SIGINT)printf(recv a sig%d\n, sig);else if (sig SIGQUIT){sigset_t uset;sigemptyset(uset);sigaddset(uset, SIGINT);sigprocmask(SIG_UNBLOCK, uset, NULL);}
} 结果 说明程序首先将SIGINT信号加入进程阻塞集屏蔽集中一开始并没有发送SIGINT信号所以进程未决集中没有处于未决态的信号当我们连续按下ctrlc时向进程发送SIGINT信号由于SIGINT信号处于进程的阻塞集中所以发送的SIGINT信号不能递达也是就是处于未决状态所以当我打印未决集合时发现SIGINT所对应的位为1现在我们按下ctrl\发送SIGQUIT信号由于此信号并没被进程阻塞所以SIGQUIT信号直接递达执行对应的处理函数在该处理函数中解除进程对SIGINT信号的阻塞所以之前发送的SIGINT信号递达了执行对应的处理函数但由于SIGINT信号是不可靠信号不支持排队所以最终只有一个信号递达。 #include signal.h
#include stdio.h
#include stdlib.h
#include error.h
#include string.h
#include unistd.h/* 版本1, 可靠信号将被递送多次 */
#define MYSIGNAL SIGRTMIN5
/* 版本2, 不可靠信号只被递送一次 */
//#define MYSIGNAL SIGTERMvoid sig_handler(int signum)
{psignal(signum, catch a signal);
}int main(int argc, char **argv)
{sigset_t block, pending;int sig, flag;/* 设置信号的handler */signal(MYSIGNAL, sig_handler);/* 屏蔽此信号 */sigemptyset(block);sigaddset(block, MYSIGNAL);printf(block signal\n);sigprocmask(SIG_BLOCK, block, NULL);/* 发两次信号, 看信号将会被触发多少次 */printf(--- send a signal ---\n);kill(getpid(), MYSIGNAL);printf(--- send a signal ---\n);kill(getpid(), MYSIGNAL);/* 检查当前的未决信号 */flag 0;sigpending(pending);for (sig 1; sig NSIG; sig) {if (sigismember(pending, sig)) {flag 1;psignal(sig, this signal is pending);} }if (flag 0) {printf(no pending signal\n);}/* 解除此信号的屏蔽, 未决信号将被递送 */printf(unblock signal\n);sigprocmask(SIG_UNBLOCK, block, NULL);/* 再次检查未决信号 */flag 0;sigpending(pending);for (sig 1; sig NSIG; sig) {if (sigismember(pending, sig)) {flag 1;psignal(sig, a pending signal);} }if (flag 0) {printf(no pending signal\n);}return 0;
} 结果 两次执行结果不同第一次连续发送两次不可靠信号最后解除阻塞时只有一个递达说明不可靠信号不支持排队。 第二次执行时连续两次发送可靠信号解除阻塞后都递达说明可靠信号支持排队。 ok这节就写到这吧