当前位置: 首页 > news >正文

三站合一网站安徽省住建厅网站官网

三站合一网站,安徽省住建厅网站官网,怎么利用网站做cpa推广,wordpress 教育 演示文章目录 三、信号的阻塞#xff08;信号的保存#xff09;1. 信号相关其他常见概念2. 在内核中的表示3. sigset_t类型4. 信号集操作函数函数列表注意事项 5. 读取/修改block位图 - sigprocmask6. 读取pending位图 - sigpending 四、信号捕捉1. 信号捕捉的初步认识自定义捕捉… 文章目录 三、信号的阻塞信号的保存1. 信号相关其他常见概念2. 在内核中的表示3. sigset_t类型4. 信号集操作函数函数列表注意事项 5. 读取/修改block位图 - sigprocmask6. 读取pending位图 - sigpending 四、信号捕捉1. 信号捕捉的初步认识自定义捕捉总结思考 2. 再谈进程地址空间内核空间与用户空间用户态和内核态 3. 内核如何实现信号的捕捉4. sigaction函数 五、信号部分的总结 #mermaid-svg-2PJfcNxhmZNCnPRA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .error-icon{fill:#552222;}#mermaid-svg-2PJfcNxhmZNCnPRA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2PJfcNxhmZNCnPRA .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-2PJfcNxhmZNCnPRA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2PJfcNxhmZNCnPRA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2PJfcNxhmZNCnPRA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2PJfcNxhmZNCnPRA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2PJfcNxhmZNCnPRA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2PJfcNxhmZNCnPRA .marker.cross{stroke:#333333;}#mermaid-svg-2PJfcNxhmZNCnPRA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2PJfcNxhmZNCnPRA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .cluster-label text{fill:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .cluster-label span{color:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .label text,#mermaid-svg-2PJfcNxhmZNCnPRA span{fill:#333;color:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .node rect,#mermaid-svg-2PJfcNxhmZNCnPRA .node circle,#mermaid-svg-2PJfcNxhmZNCnPRA .node ellipse,#mermaid-svg-2PJfcNxhmZNCnPRA .node polygon,#mermaid-svg-2PJfcNxhmZNCnPRA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2PJfcNxhmZNCnPRA .node .label{text-align:center;}#mermaid-svg-2PJfcNxhmZNCnPRA .node.clickable{cursor:pointer;}#mermaid-svg-2PJfcNxhmZNCnPRA .arrowheadPath{fill:#333333;}#mermaid-svg-2PJfcNxhmZNCnPRA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2PJfcNxhmZNCnPRA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2PJfcNxhmZNCnPRA .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-2PJfcNxhmZNCnPRA .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-2PJfcNxhmZNCnPRA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2PJfcNxhmZNCnPRA .cluster text{fill:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA .cluster span{color:#333;}#mermaid-svg-2PJfcNxhmZNCnPRA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2PJfcNxhmZNCnPRA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 信号产生 信号保存 信号处理 信号的概念和信号如何产生已经在 【Linux】进程信号概念 | 核心转储 | 信号的产生 中介绍了本文来介绍剩下的信号的保存阻塞和信号的捕捉。 三、信号的阻塞信号的保存 1. 信号相关其他常见概念 实际执行信号的处理动作称为信号递达delivery。信号从产生到递达之间的状态称为信号未决pending。进程可以选择阻塞block某个信号表示该进程当前不想收到这个信号收到后把它标记为未决但不处理它直到解除阻塞。换句话说被阻塞的信号产生时将保持在未决状态直到进程解除对此信号的阻塞才执行递达的动作。需要注意的是阻塞和忽略是不同的只要信号被阻塞就暂时不会递达而忽略是在递达之后的一种处理动作。 产生一个信号信号是未决的这个信号不一定是阻塞的。 一个信号如果被进程阻塞进程收到该信号之后一定会标记它为未决。 2. 在内核中的表示 信号在内核中的表示示意图如下 对于每个进程的pcbtask_struct对象其中的每个信号都有两个标志位分别表示阻塞block和未决pending还有一个函数指针表示处理动作 信号产生时内核在进程控制块中设置该信号的未决标志直到信号递达才清除该标志。 在示意图的例子中 SIGHUP信号未阻塞也未产生过当它递达时执行默认处理动作。SIGINT信号产生过但正在被阻塞所以暂时不能递达。虽然它的处理动作是忽略但在没有解除阻塞之前不能忽略这个信号因为进程仍有机会改变处理动作之后再解除阻塞。SIGQUIT信号未产生过一旦产生SIGQUIT信号将被阻塞它解除阻塞后会执行的处理动作是用户自定义函数sighandler()。 如果在进程解除对某信号的阻塞之前这种信号产生过多次将如何处理 POSIX.1允许系统递送该信号一次或多次。 Linux是这样实现的 常规信号在递达之前产生多次只计一次毕竟未决只能是0或1不可能记录次数。实时信号在递达之前产生多次可以依次放在一个队列里本章不讨论实时信号。 用表格整理信号位图比特位的含义和现象 信号状态比特位为1 (有效) 成因比特位为0 (有效) 成因运行现象阻塞进程使用系统调用 sigprocmask 或类似方法设置阻塞标志位进程使用系统调用 sigprocmask 或类似方法解除阻塞标志位阻塞的信号不会被处理直到解除阻塞未决信号产生且未被进程处理进程处理了一个未决信号未决的信号等待被处理直到进程执行相应信号的处理动作 用流程图整理信号传递的过程 #mermaid-svg-befk57yxboUyolNq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-befk57yxboUyolNq .error-icon{fill:#552222;}#mermaid-svg-befk57yxboUyolNq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-befk57yxboUyolNq .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-befk57yxboUyolNq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-befk57yxboUyolNq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-befk57yxboUyolNq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-befk57yxboUyolNq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-befk57yxboUyolNq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-befk57yxboUyolNq .marker.cross{stroke:#333333;}#mermaid-svg-befk57yxboUyolNq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-befk57yxboUyolNq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-befk57yxboUyolNq .cluster-label text{fill:#333;}#mermaid-svg-befk57yxboUyolNq .cluster-label span{color:#333;}#mermaid-svg-befk57yxboUyolNq .label text,#mermaid-svg-befk57yxboUyolNq span{fill:#333;color:#333;}#mermaid-svg-befk57yxboUyolNq .node rect,#mermaid-svg-befk57yxboUyolNq .node circle,#mermaid-svg-befk57yxboUyolNq .node ellipse,#mermaid-svg-befk57yxboUyolNq .node polygon,#mermaid-svg-befk57yxboUyolNq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-befk57yxboUyolNq .node .label{text-align:center;}#mermaid-svg-befk57yxboUyolNq .node.clickable{cursor:pointer;}#mermaid-svg-befk57yxboUyolNq .arrowheadPath{fill:#333333;}#mermaid-svg-befk57yxboUyolNq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-befk57yxboUyolNq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-befk57yxboUyolNq .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-befk57yxboUyolNq .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-befk57yxboUyolNq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-befk57yxboUyolNq .cluster text{fill:#333;}#mermaid-svg-befk57yxboUyolNq .cluster span{color:#333;}#mermaid-svg-befk57yxboUyolNq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-befk57yxboUyolNq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} cluster_final cluster_reached cluster_pending cluster_blocked cluster_signaled 未决 如果该信号被标记为阻塞 如果该信号未阻塞 解除阻塞 未决 解除未决 操作系统尽快让信号递达 忽略该信号 信号默认处理动作 信号的自定义捕捉 结束 结束 结束 继续运行/终止进程 执行信号处理动作 进程状态更新 - 忽略 进程状态更新 - 默认处理 进程状态更新 - 自定义处理 处理未决信号 清除未决标志 信号被阻塞 信号未决标志仍存在 设置未决标志 信号产生 cluster_unblock 3. sigset_t类型 上文提到每个信号只有一个bit的未决标志非0即1不记录该信号产生了多少次阻塞标志也是这样表示的。 未决和阻塞的标志可以用相同的数据类型sigset_t来存储 typedef unsigned long sigset_t;sigset_t就是信号位图这个类型的每个比特位可以表示对应信号的“有效”或“无效”状态 在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞。在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。 阻塞信号集也叫做当前进程的信号屏蔽字Signal Mask这里的“屏蔽”应该理解为阻塞而不是忽略。 未决标志是在信号产生时如果该信号没有被阻塞并且进程没有设置信号的忽略处理方式内核会将相应信号的未决比特位置1。 阻塞是进程的主动行为可以通过系统调用如sigprocmask来设置阻塞将特定信号的阻塞比特位置1。 4. 信号集操作函数 在Linux中sigset_t 类型用一个 bit 表示每种信号的“有效”或“无效”状态。使用者不需要关心该类型内部的数据存储方式只能通过以下函数来操作 sigset_t 变量而不应直接解释其内部数据。使用 printf 直接打印 sigset_t 变量是没有意义的。 函数列表 signal.h 中的系统调用描述int sigemptyset(sigset_t *set);初始化 set 所指向的信号集将其中所有信号的对应 bit 清零表示该信号集不包含任何有效信号。int sigfillset(sigset_t *set);初始化 set 所指向的信号集将其中所有信号的对应 bit 置位表示该信号集的有效信号包括系统支持的所有信号。int sigaddset(sigset_t *set, int signo);向 set 所指向的信号集中添加某个有效信号。int sigdelset(sigset_t *set, int signo);从 set 所指向的信号集中删除某个有效信号。int sigismember(const sigset_t *set, int signo);判断一个信号集的有效信号中是否包含某个信号。若包含则返回 1不包含则返回 0出错返回 -1。 使用一下上面的函数 #include stdio.h #include signal.h #include stdio.hint main() {sigset_t s; // 用户空间定义的变量sigemptyset(s); // 初始化 set 所指向的信号集将其中所有信号的对应 bit 清零表示该信号集不包含任何有效信号sigfillset(s); // 初始化 set 所指向的信号集将其中所有信号的对应 bit 置位表示该信号集的有效信号包括系统支持的所有信号sigaddset(s, SIGINT); // 向 set 所指向的信号集中添加某个有效信号sigdelset(s, SIGINT); // 从 set 所指向的信号集中删除某个有效信号bool test sigismember(s, SIGINT); // 判断一个信号集的有效信号中是否包含某个信号。若包含则返回 1不包含则返回 0出错返回 -1if (test)printf(true\n);elseprintf(false\n);return 0; }结果false注意事项 在使用 sigset_t 类型的变量之前必须调用 sigemptyset 或 sigfillset 进行初始化以确保信号集处于确定的状态。初始化后可以调用 sigaddset 和 sigdelset 在该信号集中添加或删除某个有效信号。 这四个函数都是成功返回 0出错返回 -1。sigismember 是一个布尔函数用于判断一个信号集的有效信号中是否包含某个信号若包含则返回 1不包含则返回 0出错返回 -1。 5. 读取/修改block位图 - sigprocmask 调用函数sigprocmask可以读取或更改进程的信号屏蔽字阻塞信号集。 #include signal.h int sigprocmask(int how, const sigset_t *set, sigset_t *oset);返回值若成功则为0若出错则为-1 使用一下 #include iostream #include unistd.h #include signal.hsigned main() {std::cout getpid: getpid() std::endl;sigset_t block, oblock;sigemptyset(block);sigemptyset(oblock);for (int signo 1; signo 31; signo) // 把1-31信号全写入block{sigaddset(block, signo); // 在这里只是修改了block变量没有让OS真正屏蔽signo号信号}sigprocmask(SIG_BLOCK, block, oblock); // 将该进程的block位图替换成我们的block位图while (true){std::cout 我已经屏蔽了所有的信号来打我呀 std::endl;sleep(1);} }使用下面的bash脚本在另外一个bash下每隔一秒kill一下该进程 i1; while :; do echo send signal:${i}...; kill -${i} 7422; sleep 1; let i; done发现除了9号和19号信号其他信号都能成功屏蔽 印证了之前说的SIGKILL (9号信号)和SIGSTOP (19号信号)不能被捕获、阻止或忽略。 6. 读取pending位图 - sigpending sigpending函数可以用于读取进程的未决信号集该函数的函数原型如下 int sigpending(sigset_t *set);sigpending函数读取当前进程的未决信号集通过set参数传出。该函数调用成功返回0出错返回-1。 实验一下 先用上述的函数将2号信号进行屏蔽阻塞。使用kill命令或组合按键向进程发送2号信号。此时2号信号会一直被阻塞并一直处于pending未决状态。使用sigpending函数获取当前进程的pending信号集进行验证。 代码 #include iostream #include unistd.h #include signal.hvoid PrintPending(const sigset_t pending) {for (int signo 1; signo 32; signo){if (sigismember(pending, signo)){std::cout 1;}else{std::cout 0;}}std::cout \n; }signed main() {sigset_t set, oset;sigemptyset(set);sigemptyset(oset);//1. 阻塞2号信号sigaddset(set, 2); //SIGINTsigprocmask(SIG_SETMASK, set, oset);//2. 让进程不断获取当前自己的pending位图sigset_t pending;sigemptyset(pending);while (1){sigpending(pending); //获取pendingPrintPending(pending); //打印pending位图1表示未决sleep(1);}return 0; }可以看到程序刚刚运行时因为没有收到任何信号所以此时该进程的pending表一直是全0而当我们使用kill命令向该进程发送2号信号后由于2号信号是阻塞的进程收到但不处理2号信号因此2号信号一直处于未决状态所以我们看到pending表中的第二个数字一直是1且进程不会退出 问题一个信号被递达pending位图会将该信号的标志位从1改成0这个修改发生在执行递达动作前还是递达动作执行完成后 我们可以让进程自定义捕捉2号信号让handler函数打印pending位图就可以验证修改pending位图的动作的发生时机 #include \iostream #include unistd.h #include signal.hvoid PrintPending(const sigset_t pending) {std::cout \n;for (int signo 1; signo 32; signo){if (sigismember(pending, signo)){std::cout 1;}else{std::cout 0;}}std::cout \n; }void handler(int signo) {sigset_t pending;sigpending(pending);PrintPending(pending);std::cout handler of signal signo std::endl; }signed main() {signal(2, handler);while (true){sleep(1);}return 0; }实际上键盘按下 CtrlC 之后向当前进程发送2号信号信号执行自定义的递达动作handler之前OS已经将pending位图由1置0了。 四、信号捕捉 1. 信号捕捉的初步认识 自定义捕捉 实际上当用户按CtrlC时这个键盘输入会产生一个硬件中断被操作系统获取并解释成信号CtrlC被解释成2号信号然后操作系统将2号信号发送给目标前台进程当前台进程收到2号信号后就会退出。 我们可以使用signal函数对2号信号进行捕捉证明当我们按CtrlC时进程确实是收到了2号信号。使用signal函数时我们需要传入两个参数第一个是需要捕捉的信号编号第二个是对捕捉信号的处理方法该处理方法的参数是int返回值是一个函数指针指向原来的信号处理函数 #include signal.htypedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);例如下面的代码中将2号信号进行了捕捉当该进程运行起来后若该进程收到了2号信号就会打印出收到信号的信号编号。 #include stdio.h #include signal.h void handler(int sig) {printf(catch a sig : %d\n, sig); } int main() {signal(2, handler); //信号是可以被自定义捕捉的siganl函数就是来进行信号捕捉的提前了解一下while(1);return 0; }总结思考 上面所说的所有信号产生最终都要有OS来进行执行为什么 因为OS是进程的管理者。 信号的处理是否是立即处理的 不是所有信号的处理都是立即进行的而是在合适的时候处理“合适的时候”是指进程从内核态返回到用户态的时候。有些信号例如 SIGKILL会立即终止进程。但对于其他信号处理可能会延迟具体取决于进程的状态以及是否被阻塞。 信号如果不是被立即处理那么信号是否需要暂时被进程记录下来记录在哪里最合适呢 是的如果信号不能立即处理需要被暂时记录下来。这通常在进程的 pending 结构体中进行记录其中包括一个位图用于表示未决信号的状态。 一个进程在没有收到信号的时候能否知道自己应该对合法信号作何处理呢 进程可以在收到信号之前通过注册信号处理函数来定义对合法信号的处理方式。这通常通过使用 signal() 或 sigaction() 系统调用来实现。进程可以指定默认的处理动作或者自定义处理函数。 如何理解OS向进程发送信号能否描述一下完整的发送处理过程 当发生触发信号的事件时例如按下 CtrlC 产生SIGINT操作系统会向相应进程发送信号。该信号会被记录在进程的 pending 位图中。如果信号不被阻塞进程会根据信号的处理方式默认动作、自定义处理函数等来执行相应的处理。如果信号被阻塞信号会在解除阻塞后递达然后按照相应的处理方式进行处理。 2. 再谈进程地址空间 内核空间与用户空间 每一个进程都有自己的进程地址空间该进程地址空间由内核空间和用户空间组成 用户所写的代码和数据位于用户空间通过用户级页表与物理内存之间建立映射关系。内核空间存储的实际上是操作系统代码和数据通过内核级页表与物理内存之间建立映射关系。内核级页表是一个全局的页表它用来维护操作系统的代码与进程之间的关系。因此: 在每个进程的进程地址空间中用户空间是属于当前进程的每个进程看到的代码和数据是完全不同的只能看到自己的那一份内核空间所存放的都是操作系统的代码和数据所有进程看到的都是一样的内容OS的代码和数据被所有内存共享。 虽然每个进程都能够看到操作系统但并不意味着每个进程都能够随时对其进行访问当进程访问用户空间时进程必须处于用户态当进程访问内核空间时进程必须处于内核态。 用户态和内核态 用户态执行用户所写的代码时就属于 用户态 内核态执行操作系统的代码时就属于 内核态 从用户态切换为内核态通常有如下几种情况 需要进行系统调用时。当前进程的时间片到了导致进程切换。产生异常、中断、陷阱等。 与之相对应从内核态切换为用户态有如下几种情况 系统调用返回时。进程切换完毕。异常、中断、陷阱等处理完毕。 其中由用户态切换为内核态我们称之为陷入内核。每当我们需要陷入内核的时本质上是因为我们需要执行操作系统的代码比如系统调用函数是由操作系统实现的我们要进行系统调用就必须先由用户态切换为内核态。 陷入内核和切换回用户态的底层实现 在 CPU 中存在一个 CR3 寄存器这个 寄存器 的作用就是用来表征当前处于 用户态 还是 内核态 当寄存器中的值为 3 时表示正在执行用户的代码也就是处于用户态当寄存器中的值为 0 时表示正在执行操作系统的代码也就是处于 内核态 3. 内核如何实现信号的捕捉 当我们在执行主控制流程的时候可能因为某些情况而陷入内核当内核处理完毕准备返回用户态时一定会进行信号pending表的检查。此时仍处于内核态有权力查看当前进程的pending位图 在查看pending位图时如果发现有未决信号并且该信号没有被阻塞那么此时就需要该信号进行处理因为处理方式有默认和自定义两种情况我们分情况讨论一下 情况1信号的默认处理如果没有用signal() 或 sigaction()来注册信号的自定义捕捉行为 如果待处理信号的处理动作是默认或者忽略则执行该信号的处理动作后清除对应的pending标志位如果没有新的信号要递达就直接返回用户态从主控制流程中上次被中断的地方继续向下执行即可。 情况2自定义捕捉用户代码中用signal() 或 sigaction()注册了信号的自定义捕捉行为 如果信号的处理动作是用户自定义函数在信号递达时就调用这个函数这就是信号的捕捉。用户程序注册了SIGQUIT信号的处理函数sighandler。 当前正在执行main函数这时发生中断或异常切换到内核态。 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。 内核决定返回用户态后不是恢复main函数的上下文继续执行而是执行sighandler函数sighandler和main函数使用不同的堆栈空间它们之间不存在调用和被调用的关系是两个独立的控制流程。 sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。 如果没有新的信号要递达这次再返回用户态就是恢复main函数的上下文继续执行了。 上面两次从内核态回到用户态的过程中都会检查pending表因为要检查有没有需要处理的信号。 简化一下上面这张图 4. sigaction函数 捕捉信号除了用前面用过的signal()函数之外我们还可以使用sigaction()函数对信号进行捕捉sigaction 比 signal 功能更丰富sigaction()函数的函数原型如下 NAMEsigaction - examine and change a signal actionSYNOPSIS#include signal.hint sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);sigaction结构体 struct sigaction {void (*sa_handler)(int); //自定义动作void (*sa_sigaction)(int, siginfo_t *, void *); //实时信号相关sigset_t sa_mask; //待屏蔽的信号集int sa_flags; //一些选项一般设为 0void (*sa_restorer)(void); //实时信号相关 };返回值成功返回 0失败返回 -1 并将错误码设置 参数1待操作的信号 参数2sigaction 结构体具体成员如上所示 参数3保存修改前进程的 sigaction 结构体信息 我们可以像使用signal()一样使用sigaction() #include iostream #include signal.h using namespace std;void PrintPending(const sigset_t pending) {std::cout 当前进程的 pending 表为: ;for (int signo 1; signo 32; signo){if (sigismember(pending, signo)){std::cout 1;}else{std::cout 0;}}std::cout \n; }void handler(int signo) {sigset_t pending;sigpending(pending);while (true){PrintPending(pending);sleep(2);} }int main() {cout 当前进程的pid getpid() endl;struct sigaction act, oact;// 初始化自定义动作act.sa_handler handler;// 给2号信号注册自定义动作sigaction(2, act, oact);while (true);return 0; }只对二号信号进行了自定义捕捉收到二号信号后不断打印pending位图此时发别的信号依然能正常终止该进程运行现象和用signal()一样 但是如果设置了sa_mask字段则当进程递达信号并执行用户自定义动作handler时可以将部分信号进行屏蔽直到用户自定义动作执行完成。 加入对345信号的屏蔽 //初始化 屏蔽信号集 sigaddset(act.sa_mask, 3); sigaddset(act.sa_mask, 4); sigaddset(act.sa_mask, 5);完整代码 #include iostream #include signal.h #include assert.h using namespace std;void PrintPending(const sigset_t pending) {std::cout 当前进程的 pending 表为: ;for (int signo 1; signo 32; signo){if (sigismember(pending, signo)){std::cout 1;}else{std::cout 0;}}std::cout \n; }void handler(int signo) {cout signo 号信号递达了 endl;sigset_t pending;int cnt 15;while (cnt--){int ret sigpending(pending);assert(ret 0);(void)ret; // 假装用一下ret欺骗编译器避免 release 模式中出错PrintPending(pending);sleep(1);} }int main() {cout 当前进程的pid getpid() endl;struct sigaction act, oact;// 初始化 自定义动作act.sa_handler handler;//初始化 屏蔽信号集 sigaddset(act.sa_mask, 3);sigaddset(act.sa_mask, 4);sigaddset(act.sa_mask, 5);// 给2号信号注册自定义动作sigaction(2, act, oact);while (true);return 0; }当 2 号信号的循环结束10 秒3、4、5 信号的 阻塞 状态解除立即被 递达进程就被干掉了 五、信号部分的总结 信号的知识按照 #mermaid-svg-MCJsVGfMWgwLqOzW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .error-icon{fill:#552222;}#mermaid-svg-MCJsVGfMWgwLqOzW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MCJsVGfMWgwLqOzW .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-MCJsVGfMWgwLqOzW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MCJsVGfMWgwLqOzW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MCJsVGfMWgwLqOzW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MCJsVGfMWgwLqOzW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MCJsVGfMWgwLqOzW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MCJsVGfMWgwLqOzW .marker.cross{stroke:#333333;}#mermaid-svg-MCJsVGfMWgwLqOzW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MCJsVGfMWgwLqOzW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .cluster-label text{fill:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .cluster-label span{color:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .label text,#mermaid-svg-MCJsVGfMWgwLqOzW span{fill:#333;color:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .node rect,#mermaid-svg-MCJsVGfMWgwLqOzW .node circle,#mermaid-svg-MCJsVGfMWgwLqOzW .node ellipse,#mermaid-svg-MCJsVGfMWgwLqOzW .node polygon,#mermaid-svg-MCJsVGfMWgwLqOzW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MCJsVGfMWgwLqOzW .node .label{text-align:center;}#mermaid-svg-MCJsVGfMWgwLqOzW .node.clickable{cursor:pointer;}#mermaid-svg-MCJsVGfMWgwLqOzW .arrowheadPath{fill:#333333;}#mermaid-svg-MCJsVGfMWgwLqOzW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MCJsVGfMWgwLqOzW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MCJsVGfMWgwLqOzW .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-MCJsVGfMWgwLqOzW .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-MCJsVGfMWgwLqOzW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MCJsVGfMWgwLqOzW .cluster text{fill:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW .cluster span{color:#333;}#mermaid-svg-MCJsVGfMWgwLqOzW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MCJsVGfMWgwLqOzW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 信号产生 信号保存 信号处理 的顺序展开 信号产生阶段有四种产生方式包括 键盘键入、系统调用、软件条件、硬件异常。信号保存阶段内核中存在三张表blcok 表、pending 表以及 handler 表信号在产生之后存储在 pending 表中。信号处理阶段信号在 内核态 切换回 用户态 时才会被处理处理方式或默认或忽略或自定义。
http://www.zqtcl.cn/news/912888/

相关文章:

  • 山东定制网页建站wordpress是是什么技术
  • 无锡免费网站制作手游网页版
  • 东莞 网站建设 定制水寻找常州微信网站建设
  • 在门户网站做推广网站开发需要20万
  • 网站做电商销售需要注册吗上海的公司地址
  • 给网站做选题计算机网络技术电商网站建设与运营方向
  • 网站如何做熊掌号并绑定wordpress pdf
  • wordpress页面构建器中文文山seo公司
  • 凡科免费做网站蜂箱尺寸与制作图片
  • 完全不收费的聊天软件班级优化大师下载安装app
  • 合肥网站改版360免费建站永久免费
  • 商业网站建设案例课程 下载工信部企业网站认证
  • 泉州网站设计哪家公司好沈阳seo代理计费
  • 做景观素材有哪几个网站国内建网站费用
  • 驻马店重点项目建设网站wordpress常规选项
  • 网站开发 英文网站策划建设阶段的推广
  • 建立网站一般多少钱wordpress评论跳过验证
  • 南京每月做社保明细在哪个网站查看设计作品的网站软件
  • html怎么做网站如何在腾讯云上网站建设
  • 网站建设怎么链接表格手机做外贸有什么好的网站
  • 深圳开发网站建设哪家好外贸网络营销培训
  • 广州智迅网络做网站免费下载ps素材网站
  • 什么网站时候做伪静态开发软件定制
  • 找人做网站 多少钱西宁市公司网站建设
  • 网页设计 教程网站找权重高的网站方法
  • 网站建设本地还是外地重庆seo排名方法
  • 那个网站做网编好昨晚兰州发生了什么事
  • 温州建设局网站首页哪里可以学做资料员的网站
  • 网站怎样在360做优化wordpress文章图片在线裁剪
  • 彭州建设网站建设网站哪间公司比较好