做网站和seo哪个好,网络服务是干什么的,怎么上传网站数据库,长春营销型网站制作1.信号的发送操作系统是所有进程的管理者#xff0c;所以对于进程的信号发送也肯定是操作系统进行操作的。其实所谓的32个普通信号#xff0c;为什么会是32个呢#xff1f;其实也刚刚好对于一个int的32个比特位#xff0c;所以说所谓的“发信号”#xff0c;本质就是操作系…1.信号的发送操作系统是所有进程的管理者所以对于进程的信号发送也肯定是操作系统进行操作的。其实所谓的32个普通信号为什么会是32个呢其实也刚刚好对于一个int的32个比特位所以说所谓的“发信号”本质就是操作系统修改进程的task_struct中的信号位图对应的比特位“发信号”更贴切的来讲是“写信号”。操作系统才是进程的管理者所以像之前使用的kill给其他进程发送信号也必然是经过操作系统的手修改的。2.信号的保存2.1概念介绍实际执行信号的处理动作称为信号递达Delivery信号从产生到递达之间的状态即此时信号被保存起来了称为信号未决Pending进程可以选择阻塞/屏蔽Block某个信号当信号被阻塞/屏蔽之后不会处理这个信号即信号不会被递达如果一个信号此时已经被阻塞那么当进程收到了这个被阻塞的信号之后不会处理这个信号但是仍然会保存这个信号此时这个信号处于信号未决状态直到进程解除了对这个信号的阻塞之后此时这个信号才会被处理即此时信号才会被递达信号的处理动作有1. 默认动作2. 忽略3. 用户自定义动作值得注意的是阻塞和忽略是两种完全不同的概念1. 对于阻塞只要信号被阻塞那么信号就不会被递达。2. 对于忽略忽略则是信号在递达之后可选的一种处理动作2.2 信号未决信号阻塞/屏蔽信号处理每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志将对于位置的0设为1,直到信号递达才清除该标志。block表示进程是否被阻塞也是以位图的形式来表示如果2信号被阻塞就把对于的比特位置为1表示被阻塞。pending表示信号是否收到如果收到就置为1。handler表示信号的处理方式是SIG_DFL默认处理动作SIG_IGN忽略动作还是用户传入的自定义动作所以signal函数不就是将信号的handler表中的设置成自己的函数。SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,也就是不能对这个信号进行操作因为进程仍有机会改变处理动作之后再解除阻塞。SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。 如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。本章不讨论实时信号ps这里要分清楚信号递达和信号未决信号递达表示的是进程已经收到信号了但是还没有处理信号未决指的是信号发送了但是我还没有收到一个是完成态一个是进行态。测试SIG_DFL默认行为,SIG_IGN忽略行为SIG_IGN忽略行为将2号信号ctrlc的处理动作变为忽略。#include iostream #include signal.h #include unistd.h using namespace std; int main() { signal(2, SIG_IGN); while(true) { cout hello linux endl; sleep(1); } return 0; }运行结果对2号信号忽略不处理SIG_DFL默认行为将2号信号ctrlc的处理动作设置为默认。#include iostream #include signal.h #include unistd.h using namespace std; int main() { signal(2, SIG_DFL); while(true) { cout hello linux endl; sleep(1); } return 0; }运行结果采取默认动作终止进程。2.3 sigset_t 信号集从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。下一节将详细介绍信号集的各种操作。 阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。2.3.1 信号集操作函数#include signal.h int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset (sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigismemberconst sigset_t *set, int signo);操作系统是不相信任何人的所以对于信号集的操作它提供了接口来提供给用户进行操作。sigemptyset是初始化信号集将信号集的所有比特位设置0sigfillset同样是初始化信号集将信号集所有比特位设置为1sigaddset是将信号集的信号编号signo号信号的比特位设置为1sigdelset是将信号集的信号编号signo信号的比特位设置为0上述接口的返回值都是成功了返回0出错了返回-1sigismember是检查信号集的信号编号signo信号的比特位是否为1即信号是否存在如果比特位为1那么表示信号存在返回1如果比特位为0那么表示信号不存在返回0如果出错返回-1ps注意在使用上图函数的时候不要忘记将set进行取地址传入2.3.2 sigprocmasksigprocmask是用来读取或者更改进程的信号屏蔽字阻塞信号集/block信号集#include signal.h int sigprocmask(int how, const sigset_t *set, sigset_t *oset);set是我们想要带传输给进程PCB的信号集。oset输入输出型参数会将原本的阻塞信号集拷贝到oset中。返回值:若成功则为0,若出错则为-1如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则 更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设原来的信号屏蔽字为mask,下表说明了how参数的可选值。只可以3选1。2.3.3 sigpending读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。2.4 代码测试测试1是否可以把所有的信号都阻塞思路利用sigaddset设置一个比特位全部都是1的信号集通过sigprocmask设置how为SIG_SETMASK覆盖掉原来的比特位这样子把所有的信号都阻塞住之后利用sigpending获取未决信号集利用sigismember检查未决信号集上面的比特位打印出来另外打开终端发送1-31号信号由于信号被阻塞不会被处理但是未决信号集上的比特位会显示1。1 #includeiostream 2 #includeunistd.h 3 #includesignal.h 4 using namespace std; 5 void printpending(sigset_t pending) 6 { 7 for(int sig31;sig1;sig--) 8 { 9 if(sigismember(pending,sig)) 10 { 11 cout1; 12 } 13 else 14 { 15 cout0; 16 } 17 } 18 coutendl; 19 } 20 21 int main() 22 { 23 sigset_t bset,oset; 24 sigemptyset(bset); 25 sigemptyset(oset); 26 for(int i0;i31;i) 27 { 28 sigaddset(bset,i); 29 } 30 sigprocmask(SIG_BLOCK,bset,oset);//不可以阻塞所有的信号919不行 31 sigset_t pending; 32 sigemptyset(pending); 33 while(true) 34 { 35 int nsigpending(pending); 36 printpending(pending); 37 sleep(1); 38 } 39 }那么接下来小编将进程运行起来同时使用ps axj | grep mysignal | grep -v grep找到我们进程的pid接下来使用kill指令开始发送信号。当发送到9号信号的时候此时在左侧我们可以看到进程被9号信号杀掉了即代表9号信号不可以被屏蔽/阻塞那么小编接下来重新运行将进程运行起来开始从10号信号进行发送当发送到18号信号的时候此时在左侧我们已经可以看到了有9个1了即代表10到18号信号都可以被屏蔽/阻塞当发送到19号信号的时候此时在左侧我们可以看到进程被19号信号暂停了即代表19号信号不可以被屏蔽/阻塞接下来将对应的进程使用9号信号杀掉避免后续对我们的测试产生干扰那么接下来重新运行将进程运行起来开始从20号信号进行发送当发送到31号信号的时候此时在左侧我们已经可以看到了有12个1了即代表20到31号信号都可以被屏蔽/阻塞