自己创建网站怎么赚钱,wordpress口语主题,云虚拟主机怎么建网站,2018网站的建设与维护前景目录
1 信号集、信号的阻塞
2 信号集操作函数
2.1 自定义信号集
2.2 清空信号集
2.3 全部置1
2.4 将一个信号添加到集合中
2.5 将一个信号从集合中移除
2.6 判断一个信号是否在集合中
2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞)
2.8 使进程挂起#xff08;…目录
1 信号集、信号的阻塞
2 信号集操作函数
2.1 自定义信号集
2.2 清空信号集
2.3 全部置1
2.4 将一个信号添加到集合中
2.5 将一个信号从集合中移除
2.6 判断一个信号是否在集合中
2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞)
2.8 使进程挂起暂停执行直到收到一个信号
2.9 更改进程的信号屏蔽字并等待一个特定的信号到来 掌握信号集和信号屏蔽
1 信号集、信号的阻塞
应用
有时候不希望在接到信号时就立即停止当前执行去处理信号同时也不希望忽略该信号而是延
时一段时间去调用信号处理函数。这种情况可以通过阻塞信号实现。
信号的阻塞概念
信号的”阻塞“是一个开关动作指的是阻止信号被处理但不是阻止信号产生。
信号的状态
信号递达Delivery 实际信号执行的处理过程(3种状态忽略执行默认动作捕获)
信号未决Pending从产生到递达之间的状态(挂起
下图表示了每一个任务控制块都有一个挂起信号集可读和信号屏蔽字可写可读。信号屏蔽置1代表忽略该信号的到来 2 信号集操作函数
2.1 自定义信号集
sigset_t set;
自定义信号集。 是一个 64bit 128bit的数组。
2.2 清空信号集
sigemptyset(sigset_t *set);
代表接收所有信号
2.3 全部置1
sigfillset(sigset_t *set);
接收全部信号
2.4 将一个信号添加到集合中
sigaddset(sigset_t *set, int signum);
接收某一个位的信号
2.5 将一个信号从集合中移除
sigdelset(sigset_t *set, int signum);
屏蔽某一个位的信号
2.6 判断一个信号是否在集合中
sigismemberconst sigset_t *setint signum);
2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞)
#include signal.h
int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset );
参数说明
how表示如何修改信号屏蔽字的标志可取以下值 SIG_BLOCK将set中指定的信号添加到当前信号屏蔽字中。SIG_UNBLOCK将set中指定的信号从当前信号屏蔽字中移除。SIG_SETMASK用set中指定的信号集替换当前信号屏蔽字。set指向要修改的新的信号屏蔽字的指针。如果为NULL则不会修改信号屏蔽字。oset用于保存旧的信号屏蔽字的指针。如果为NULL则不会保存旧的信号屏蔽字。
函数返回值
成功返回0并将旧的信号屏蔽字保存到oset中如果oset不为NULL。失败返回-1并设置errno来指示错误的原因。
该函数用于在多线程编程、信号处理等场景中控制信号的屏蔽以保证信号处理的正确性和可靠性。
示例
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig){printf(I get sig%d\n,sig);}int main(){struct sigaction act;act.sa_handler handle; //注册回调函数sigemptyset(act.sa_mask); //清空信号集代表接收所有信号act.sa_flags 0; //通过将其设置为0表示不使用任何额外的标志位即默认行为。sigaction(SIGINT,act,NULL); //信号捕获sigset_t set; //定义信号集sigemptyset(set); //清空信号集sigaddset(set,SIGINT); //SIGINT屏蔽SIGINT信号sigprocmask(SIG_BLOCK,set,NULL); //ctrlc的信号阻塞接收不到sleep(5);sigprocmask(SIG_UNBLOCK,set,NULL); //取消信号阻塞while(1){sleep(1);}}执行效果 2.8 使进程挂起暂停执行直到收到一个信号
int pause(void);
进程一直阻塞直到被信号中断返回值-1 并设置errno为EINTR
函数行为
-1 如果信号的默认处理动作是终止进程则进程终止pause函数没有机会返回。
-2 如果信号的默认处理动作是忽略进程继续处于挂起状态pause函数不返回
-3 如果信号的处理动作是捕捉则调用完信号处理函数之后pause返回-1。
-4 pause收到的信号如果被屏蔽那么pause就不能被唤醒
示例pause阻塞效果
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hint main(int argc, char * argv[])
{pause();printf(after pause\n);
}//运行后结果程序阻塞中未打印after pause按ctrlc或ctrl\结束
linuxlinux:~/Desktop$ ./pause 示例pause阻塞效果2
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig)
{printf(Handle:I get sig%d\n,sig);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler handle;act.sa_flags 0;sigemptyset(act.sa_mask);sigaction(SIGINT,act,NULL);pause();printf(after pause\n);
}//运行结果未恢复至原处理函数的执行效果
linuxlinux:~/Desktop$ ./pause
^CHandle:I get sig2
after pause
linuxlinux:~/Desktop$ 示例pause阻塞效果3 实现一个等待信号的任务
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig)
{printf(Handle:I get sig%d\n,sig);
}void mytask()
{printf(mytask:start\n);sleep(3);printf(mytask:end\n);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler handle;act.sa_flags 0;sigemptyset(act.sa_mask);sigaction(SIGINT,act,NULL);pause();while(1){mytask(); pause(); //每次等待信号到来再执行mytask}printf(After pause\n);
} //运行结果
linuxlinux:~/Desktop$ ./pause
^CHandle:I get sig2
mytask:start
mytask:end
^CHandle:I get sig2
mytask:start
mytask:end
^CHandle:I get sig2
mytask:start
mytask:end
使用kill 发送SIGHUP信号关闭 示例pause阻塞效果4 实现一个等待多个信号的任务SIGINTSIGHUP
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig)
{printf(Handle:I get sig%d\n,sig);
}void mytask()
{printf(mytask:start\n);sleep(3);printf(mytask:end\n);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler handle;act.sa_flags 0;sigemptyset(act.sa_mask);sigaction(SIGINT,act,NULL);sigaction(SIGHUP,act,NULL); pause();while(1){mytask();pause();}printf(After pause\n);
}
按ctrlc或者使用kill -1发送关闭信号都可以捕获信号处理任务。 示例使用 sigaddset屏蔽多个信号
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig)
{printf(Handle:I get sig%d\n,sig);
}void mytask()
{printf(mytask:start\n);sleep(3);printf(mytask:end\n);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler handle;act.sa_flags 0;sigemptyset(act.sa_mask);sigaction(SIGINT,act,NULL);sigaction(SIGHUP,act,NULL);sigset_t set;sigaddset(set,SIGHUP);sigaddset(set,SIGINT); pause();while(1){sigprocmask(SIG_BLOCK,set,NULL);mytask();sigprocmask(SIG_UNBLOCK,set,NULL);pause();}printf(After pause\n);
}
执行效果在任务过程中设置了信号屏蔽此时按ctrlc或者kill -1去发送信号不会执行handle打印直到任务结束后再开启接收信号防止任务被打断 2.9 更改进程的信号屏蔽字并等待一个特定的信号到来
设定对信号集内的信号屏蔽并恢复。
int sigsuspend(const sigset_t *sigmask);
功能函数用于临时更改进程的信号屏蔽字并等待一个特定的信号到来然后恢复原有的信号屏蔽字。和 pause 函数不同的是它可以临时更改进程的信号屏蔽字以便等待某个特定信号。
参数
sigmask希望屏蔽的信号
示例解决任务中的信号丢失问题sigsuspend相当于sigprocmaskpause
#include signal.h
#include stdio.h
#include stdlib.h
#include unistd.hvoid handle(int sig)
{printf(Handle:I get sig%d\n,sig);
}void mytask()
{printf(mytask:start\n);sleep(3);printf(mytask:end\n);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler handle;act.sa_flags 0;sigemptyset(act.sa_mask);sigaction(SIGINT,act,NULL);sigaction(SIGHUP,act,NULL);sigset_t set;sigaddset(set,SIGHUP);sigaddset(set,SIGINT); sigset_t set2; sigemptyset(set2); //接收所有信号pause();while(1){sigprocmask(SIG_BLOCK,set,NULL);mytask();//sigprocmask(SIG_UNBLOCK,set,NULL);//pause();sigsuspend(set2);}printf(After pause\n);
}
运行结果
linuxlinux:~/Desktop$ ./pause
^CHandle:I get sig2 //1次CTRLC
mytask:start
mytask:end
^CHandle:I get sig2 //1次CTRLC
mytask:start
mytask:end
^CHandle:I get sig2 //1次CTRLC
mytask:start
^Cmytask:end //任务中途的1次CTRLC
Handle:I get sig2 //也被获取到并执行了
mytask:start
mytask:end