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

wordpress 做外贸站品牌建设题目

wordpress 做外贸站,品牌建设题目,山东省住房和城乡建设厅职称评审,柳州正规网站制作目录 前言#xff1a; 1、再次认识信号 1.1、概念 1.2、感性理解 1.3、在内核中的表示 1.4、sigset_t 信号集 2、信号集操作函数 2.1、增删改查 2.2、sigprocmask 2.3、sigpending 3.信号的处理机制 3.1处理情况 3.2合适时机 4用户态与内核态 4.1、概念 4.2、… 目录 前言 1、再次认识信号 1.1、概念 1.2、感性理解 1.3、在内核中的表示 1.4、sigset_t 信号集 2、信号集操作函数 2.1、增删改查 2.2、sigprocmask 2.3、sigpending 3.信号的处理机制 3.1处理情况  3.2合适时机 4用户态与内核态 4.1、概念 4.2、重谈进程地址空间 4.3、信号的处理过程 5.信号捕捉 5.1、内核如何实现信号的捕捉 5.2sigaction  6 小结 前言 信号从产生到执行并不会被立即处理这就意味着需要一种 “方式” 记录信号是否产生对于 31 个普通信号来说一个 int 整型就足以表示所有普通信号的产生信息了信号还有可能被 “阻塞”对于这种多状态、多结果的事物操作系统会将其进行描述、组织、管理这一过程称为 信号保存 阶段 1、再次认识信号 补充 信号传递 的相关概念 1.1、概念 信号 传递过程信号产生 - 信号未决 - 信号递达 信号产生Produce由四种不同的方式发出信号 信号未决Pending信号从 产生 到 执行 的中间状态 信号递达Delivery进程收到信号后对信号的处理动作 在这三种过程之前均有可能出现 信号阻塞 的情况 信号阻塞Block使信号传递 “停滞”无论是否产生都无法进行处理 信号递达后的三种处理方式 SIG_DFL 默认处理动作大多数信号最终都是终止进程SIG_IGN 忽略动作即进程收到信号后不做任何处理动作handler 用户自定义的信号执行动作   注意 信号阻塞 是一种手段可以发生在 信号处理 前的任意时段信号阻塞 与 忽略动作 不一样虽然二者的效果差不多什么都不干但前者是 干不了后者则是 不干了需要注意区分 1.2、感性理解 将 信号传递 的过程比作 网上购物 可以抽象出以下概念 信号产生在某某购物平台上下达了订单信号未决订单下达后快递的运输过程信号递达快递到达驿站后你对于快递的处理动作信号阻塞快递运输过程中堵车了 只要你下单了你的手机上肯定会有 物流信息未决信息已记录当 快递送达后信号递达物流记录 不再更新 而 堵车 是一件不可预料的事情也就是说在下单后快递可能一会儿送达没有阻塞可能五天送达阻塞 - 解除阻塞有可能永不送达因为快递可能永远堵车阻塞 堵车也有可能在你下单前发生信号产生前阻塞 至于 信号递达后的处理动作 如何理解呢 快递送达后正常拆快递默认动作 快递送达后啥也不干就是玩忽略 快递送达后直接把快递退回去用户自定义 当然用户自定义的情况可以有很多种也有可能是直接把快递扔了 综上网购的整个过程可以看作 信号传递过程本文探讨的是 信号保存阶段即 物流信息 1.3、在内核中的表示 对于传递中的信号来说需要存在三种状态表达 信号是否阻塞信号是否未决信号递达时的执行动作 在内核中每个进程都需要维护这三张与信号状态有关的表block 表、pending 表、handler 表 所谓的 block 表 和 pending 表 其实就是 位图结构 一个 整型 int 就可以表示 31 个普通信号实时信号这里不讨论 比如 1 号信号就是位图中的 0 位置处0 表示 未被阻塞/未产生未决1 则表示 阻塞/未决 对于信号的状态修改其实就是修改 位图 中对应位置的值0/1 对于多次产生的信号只会记录一次信息实时信号则会将冗余的信号通过队列组织 如何记录信号已产生 - 未决表中对应比特位置置为 1 假设已经获取到了信号的 pending 表 只需要进行位运算即可pending | (1 (signo - 1)) 其中的 signo 表示信号编号-1 是因为信号编号从 1 开始需要进行偏移 如果想要取消 未决 状态也很简单pending (~(1 (signo - 1))) 至于 阻塞 block 表与 pending 表 一模一样 对于上图的解读 SIGHUP 信号未被阻塞未产生一旦产生了该信号pending 表对应的位置置为 1当信号递达后执行动作为默认SIGINT 信号被阻塞已产生pending 表中有记录此时信号处于阻塞状态无法递达一旦解除阻塞状态信号递达后执行动作为忽略该信号SIGQUIT 信号被阻塞未产生即使产生了也无法递达除非解除阻塞状态执行动作为自定义 阻塞 block 与 未决 pending 之间并没很强的关联性阻塞不过是信号未决的延缓剂 信号在 产生 之前可以将其 阻塞信号在 产生 之后未决依然可以将其 阻塞 至于 handler 表是一个 函数指针表格式为返回值为空参数为 int 的函数 可以看看 默认动作 SIG_DEL 和 忽略动作 SIG_IGN 的定义 /* Type of a signal handler. */ typedef void (*__sighandler_t) (int);/* Fake signal functions. */ #define SIG_ERR ((__sighandler_t) -1) /* Error return. */ #define SIG_DFL ((__sighandler_t) 0) /* Default action. */ #define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */默认动作就是将 0 强转为函数指针类型忽略动作则是将 1 强转为函数指针类型分别对应 handler 函数指针数组表中的 0、1 下标位置除此之外还有一个 错误 SIG_ERR 表示执行动作为 出错 简单对这三张表作一个总结task_struct 中存在 block 表位图结构比特位的位置表示哪一个信号比特位的内容代表 是否 对应信号被阻塞 pending 表位图结构比特位的位置表示哪一个信号比特位的内容代表 是否 收到该信号 handler 表函数指针数组该数组的下标表示信号编号数组的特定下标的内容表示该信号递达后的执行动作 1.4、sigset_t 信号集 无论是 block 表 还是 pending 表都是一个位图结构依靠 除、余 完成操作为了确保不同平台中位图操作的兼容性将信号操作所需要的 位图 结构封装成了一个结构体类型其中是一个 无符号长整型数组 /* A sigset_t has a bit for each signal. */# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) typedef struct{unsigned long int __val[_SIGSET_NWORDS];} __sigset_t;#endif注_SIGSET_NWORDS 大小为 32所以这是一个可以包含 32 个 无符号长整型 的数组而每个 无符号长整型 大小为 4 字节即 32 比特至多可以使用 1024 个比特位 sigset_t 是信号集其中既可以表示 block 表信息也可以表示 pending 表信息可以通过信号集操作函数进行获取对应的信号集信息信号集 的主要功能是表示每个信号的 “有效” 或 “无效” 状态 block 表 通过信号集称为 阻塞信号集或信号屏蔽字屏蔽表示阻塞pending 表 通过信号集中称为 未决信号集 如何根据 sigset_t 位图结构进行比特位的操作 假设现在要获取第 127 个比特位 首先定位数组下标对哪个数组操作127 / (8 * sizeof (unsigned long int)) 3 求余获取比特位对哪个比特位操作127 % (8 * sizeof (unsigned long int)) 31 对比特位进行操作即可 假设待操作对象为 XXX 置 1XXX._val[3] | (1 31) 置 0XXX._val[3] (~(1 31)) 所以可以仅凭 sigset_t 信号集对 1024 个比特位进行任意操作关于 位图 结构的实现后续介绍 2、信号集操作函数 对于 信号 的 产生或阻塞 其实就是对 block 和 pending 两张表的 增删改查 2.1、增删改查 对于 位图 的 增删改查 是这样操作的 增| 操作将比特位置为 1 删 操作将比特位置为 0 改| 或 操作灵活变动 查判断指定比特位是否为 1 即可 比特作为基本单位不推荐让我们直接进行操作操作系统也不同意于是提供了一批 系统接口用于对 信号集 进行操作 #include signal.hint 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); //查 这些函数都是 成功返回 0失败返回 -1 至于参数非常简单无非就是 待操作的信号集变量、待操作的比特位 注意 在创建 信号集 sigset_t 类型后需要使用 sigemptyset 或 sigfillset 函数进行初始化确保 信号集 是合法可用的 2.2、sigprocmask sigprocmask 函数可用用来对 block 表 进行操作 #include signal.hint sigprocmask(int how, const sigset_t *set, sigset_t *oldset);返回值成功返回 0失败返回 -1 并将错误码设置 参数1对 屏蔽信号集 的操作 SIG_BLOCK 希望添加至当前进程 block 表 中阻塞信号从 set 信号集中获取相当于 mask | set SIG_UNBLOCK 解除阻塞状态也是从 set 信号集中获取相当于 mask (~set) SIG_SETMASK 设置当前进程的 block 表为 set 信号集中的 block 表相当于 mask set 参数2就是一个信号集主要从此信号集中获取屏蔽信号信息 参数3也是一个信号集保存进程中原来的 block 表相当于给你操作后反悔的机会 这个函数就是 参数 1 比较有讲究主打的就是一个 从 set 信号集 中获取阻塞信号相关信息然后对进程中的 block 表进行操作并且有三种不同的操作方式 演示程序1将 2 号信号阻塞尝试通过 键盘键入 发出 2 信号 #include iostream #include unistd.h #include signal.h using namespace std;int main() {//创建信号集sigset_t set, oset;//初始化信号集sigemptyset(set);sigemptyset(oset);//阻塞2号信号sigaddset(set, 2); //2 号信号被记录//设置当前进程的 block 表sigprocmask(SIG_BLOCK, set, oset);//死循环while(true){cout 我是一个进程我正在运行 endl;sleep(1);}return 0; }显然当 2 号信号被阻塞后是 无法被递达 的进程也就无法终止了 演示程序2在程序运行五秒后解除阻塞状态 #include iostream #include unistd.h #include signal.h using namespace std;int main() {// 创建信号集sigset_t set, oset;// 初始化信号集sigemptyset(set);sigemptyset(oset);// 阻塞2号信号sigaddset(set, 2); //2 号信号被记录// 设置当前进程的 屏蔽信号集sigprocmask(SIG_BLOCK, set, oset);// 死循环int n 0;while (true){if (n 5){// 采用 SIG_SETMASK 的方式覆盖进程的 block 表sigprocmask(SIG_SETMASK, oset, nullptr); // 不接收进程的 block 表}cout 我是一个进程我正在运行 endl;n;sleep(1);}return 0; }现象在 2 号信号发出、程序运行五秒解除阻塞后信号才被递达进程被终止 如何证明信号已递达 当 n 5 时解除阻塞状态程序立马结束 并只打印了 五条 语句证明在第六秒时程序就被终止了 至于如何进一步证明需要借助 未决信号表 2.3、sigpending 这个函数很简单获取当前进程中的 未决信号集 #include signal.hint sigpending(sigset_t *set);返回值成功返回 0失败返回 -1 并将错误码设置 参数待获取的 未决信号集 如何根据 未决信号集 打印 pending 表 使用函数 sigismember 判断当前信号集中是否存在该信号如果存在输出 1否则输出 0如此重复将 31 个信号全部判断打印输出即可 #include iostream #include cassert #include unistd.h #include signal.h using namespace std;static void DisplayPending(const sigset_t pending) {//打印 pending 表cout 当前进程的 pending 表为: ;int i 1;while(i 32){if(sigismember(pending, i))cout 1;elsecout 0;i;}cout endl; }int main() {// 创建信号集sigset_t set, oset;// 初始化信号集sigemptyset(set);sigemptyset(oset);// 阻塞2号信号sigaddset(set, 2); //记录 2 号信号// 设置当前进程的 屏蔽信号集sigprocmask(SIG_BLOCK, set, oset);// 死循环int n 0;while (true){if (n 5){// 采用 SIG_SETMASK 的方式覆盖进程的 block 表sigprocmask(SIG_SETMASK, oset, nullptr); // 不接收进程的 block 表}//获取进程的 未决信号集sigset_t pending;sigemptyset(pending);int ret sigpending(pending);assert(ret 0);(void)ret; //欺骗编译器避免 release 模式中出错DisplayPending(pending);n;sleep(1);}return 0; }结果当 2 号信号发出后当前进程的 pending 表中的 2 号信号位被置为 1表示该信号属于 未决 状态并且在五秒之后阻塞结束信号递达进程终止 疑问当阻塞解除后信号递达应该看见 pending 表中对应位置的值由 1 变为 0但为什么没有看到 很简单因为当前 2 号信号的执行动作为终止进程进程都终止了当然看不到 解决方法给 2 号信号先注册一个自定义动作别急着退出进程 #include iostream #include cassert #include unistd.h #include signal.h using namespace std;static void handler(int signo) {cout signo 号信号确实递达了 endl;//最终不退出进程 }static void DisplayPending(const sigset_t pending) {// 打印 pending 表cout 当前进程的 pending 表为: ;int i 1;while (i 32){if (sigismember(pending, i))cout 1;elsecout 0;i;}cout endl; }int main() {// 更改 2 号信号的执行动作signal(2, handler);// 创建信号集sigset_t set, oset;// 初始化信号集sigemptyset(set);sigemptyset(oset);// 阻塞2号信号sigaddset(set, 2); //记录 2 号信号// 设置当前进程的 屏蔽信号集sigprocmask(SIG_BLOCK, set, oset);// 死循环int n 0;while (true){if (n 5){// 采用 SIG_SETMASK 的方式覆盖进程的 block 表sigprocmask(SIG_SETMASK, oset, nullptr); // 不接收进程的 block 表}// 获取进程的 未决信号集sigset_t pending;sigemptyset(pending);int ret sigpending(pending);assert(ret 0);(void)ret; // 欺骗编译器避免 release 模式中出错DisplayPending(pending);n;sleep(1);}return 0; }显然这就是我们想要的最终结果 先将信号 阻塞信号发出后无法 递达始终属于 未决 状态当阻塞解除后信号可以 递达信号处理之后未决 表中不再保存信号相关信息因为已经处理了 综上信号在发出后在处理前都是保存在 未决表 中的 注意 针对信号的 增删改查 都需要通过 系统调用 来完成不能擅自使用位运算 sigprocmask、sigpending 这两个函数的参数都是 信号集前者是 屏蔽信号集后者是 未决信号集 在对 信号集 进行增删改查前一定要先初始化 信号在被解除 阻塞状态 后很快就会 递达 了 关于信号何时递达、以及递达后的处理动作在下一篇文章中揭晓 以上关于 信号、信号集 的操作都是在进程中进行的不影响操作系统 3.信号的处理机制 3.1处理情况  普通情况 所谓的普通情况就是指 信号没有被阻塞直接产生记录未决信息后再进行处理 在这种情况下信号是不会被立即递达的也就无法立即处理需要等待合适的时机 特殊情况 当信号被 阻塞 后信号 产生 时记录未决信息此时信号被阻塞了也不会进行处理 当阻塞解除后信号会被立即递达此时信号会被立即处理 特殊情况 很好理解就好比往气球里吹气当气球炸了空气会被立即释放因为空气是被气球 阻塞 的当气球炸了之后阻塞 解除空气立马往外跑这不就是 立即递达、立即处理 吗 3.2合适时机 信号的产生是 异步 的 也就是说信号可能随时产生当信号产生时进程可能在处理更重要的事此时贸然处理信号显然不够明智 比如进程正在执行一个重要的 IO突然一个终止信号发出IO 立即终止对进程、磁盘都不好 因此信号在 产生 后需要等进程将 更重要 的事忙完后合适的时机才进行 处理 合适的时机进程从 内核态 返回 用户态 时会在操作系统的指导下对信号进行检测及处理 至于处理动作分为默认动作、忽略、用户自定义 搞清楚 “合适” 的时机 后接下来需要学习 用户态 和 内核态 相关知识 4用户态与内核态 对于 用户态、内核态 的理解及引出的 进程地址空间 和 信号处理过程 相关知识是本文的重难点 4.1、概念 先来看看什么是 用户态和内核态 用户态执行用户所写的代码时就属于 用户态 内核态执行操作系统的代码时就属于 内核态 自己写的代码被执行很好理解操作系统的代码是什么 操作系统也是由大量代码构成的在对进程进行调度、执行系统调用、异常、中断、陷阱等都需要借助操作系统之手此时执行的就是操作系统的代码   也就是说用户态 与 内核态 是两种不同的状态必然存在相互转换的情况 用户态 切换为 内核态 当进程时间片到了之后进行进程切换动作 调用系统调用接口比如 open、close、read、write 等 产生异常、中断、陷阱等内核态 切换为 用户态 进程切换完毕后运行相应的进程 系统调用结束后 异常、中断、陷阱等处理完毕 信号的处理时机就是 内核态 切换为 用户态也就是 当把更重要的事做完后进程才会在操作系统的指导下对信号进行检测、处理 下面来结合 进程地址空间 深入理解 操作系统的代码 及 状态切换 的相关内容拓展知识 4.2、重谈进程地址空间 首先简单回顾下 进程地址空间 的相关知识 进程地址空间 是虚拟的依靠 页表MMU机制 与真实的地址空间建立映射关系 每个进程都有自己的 进程地址空间不同 进程地址空间 中地址可能冲突但实际上地址是独立的 进程地址空间 可以让进程以统一的视角看待自己的代码和数据 不难发现在 进程地址空间 中存在 1 GB 的 内核空间每个进程都有而这 1 GB 的空间中存储的就是 操作系统 相关 代码 和 数据并且这块区域采用 内核级页表 与 真实地址空间 进行映射 为什么要区分 用户态 与 内核态  内核空间中存储的可是操作系统的代码和数据权限非常高绝不允许随便一个进程对其造成影响区域的合理划分也是为了更好的进行管理 所谓的 执行操作系统的代码及系统调用就是在使用这 1 GB 的内核空间  进程间具有独立性比如存在用户空间中的代码和数据是不同的难道多个进程需要存储多份 操作系统的代码和数据 吗 当然不用内核空间比较特殊所有进程最终映射的都是同一块区域也就是说进程只是将 操作系统代码和数据 映射入自己的 进程地址空间 而已 而 内核级页表 不同于 用户级页表专注于对 操作系统代码和数据 进行映射是很特殊的 当我们执行诸如 open 这类的 系统调用 时会跑到 内核空间 中调用对应的函数 而 跑到内核空间 就是 用户态 切换为 内核态 了用户空间切换至内核空间 这个 跑到 是如何实现的呢 在 CPU 中存在一个 CR3 寄存器这个 寄存器 的作用就是用来表征当前处于 用户态 还是 内核态 当寄存器中的值为 3 时表示正在执行用户的代码也就是处于 用户态 当寄存器中的值为 0 时表示正在执行操作系统的代码也就是处于 内核态 通过一个 寄存器表征当前所处的 状态修改其中的 值就可以表示不同的 状态这是很聪明的做法 重谈 进程地址空间 后得到以下结论 所有进程的用户空间 [0, 3] GB 是不一样的并且每个进程都要有自己的 用户级页表 进行不同的映射 所有进程的内核空间 [3, 4] GB 是一样的每个进程都可以看到同一张内核级页表从而进行统一的映射看到同一个 操作系统 操作系统运行 的本质其实就是在该进程的 内核空间内运行的最终映射的都是同一块区域 系统调用 的本质其实就是在调用库中对应的方法后通过内核空间中的地址进行跳转调用 那么进程又是如何被调度的呢 操作系统的本质 - 操作系统也是软件啊并且是一个死循环式等待指令的软件 - 存在一个硬件操作系统时钟硬件每隔一段时间向操作系统发送时钟中断 进程被调度就意味着它的时间片到了操作系统会通过时钟中断检测到是哪一个进程的时间片到了然后通过系统调用函数 schedule() 保存进程的上下文数据然后选择合适的进程去运行 4.3、信号的处理过程 当在 内核态 完成某种任务后需要切回 用户态此时就可以对信号进行 检测 并 处理 了 情况1信号被阻塞信号产生/未产生 信号都被阻塞了也就不需要处理信号此时不用管直接切回 用户态 就行了 下面的情况都是基于 信号未被阻塞 且 信号已产生 的前提 情况2当前信号的执行动作为 默认 大多数信号的默认执行动作都是 终止 进程此时只需要把对应的进程干掉然后切回 用户态 就行了 情况3当前信号的执行动作为 忽略  当信号执行动作为 忽略 时不做出任何动作直接返回 用户态 情况4当前信号的执行动作为 用户自定义  这种情况就比较麻烦了用户自定义的动作位于 用户态 中也就是说需要先切回 用户态把动作完成了重新坠入 内核态最后才能带着进程的上下文相关数据返回 用户态 在 内核态 中也可以直接执行 自定义动作为什么还要切回 用户态 执行自定义动作 因为在 内核态 可以访问操作系统的代码和数据自定义动作 可能干出危害操作系统的事 在 用户态 中可以减少影响并且可以做到溯源 为什么不在执行完 自定义动作 直接后返回进程 因为 自定义动作 和 待返回的进程 属于不同的堆栈是无法返回的 并且进程的上下文数据还在内核态中所以需要先坠入内核态才能正确返回用户态 注意 用户自定义的动作需要先切换至 用户态 中执行执行结束后还需要坠入 内核态 通过一张图快速记录信号的 处理 过程 5.信号捕捉 接下来谈谈 信号 是如何被 捕捉 的 5.1、内核如何实现信号的捕捉 如果信号的执行动作为 用户自定义动作当信号 递达 时调用 用户自定义动作这一动作称为 信号捕捉 用户自定义动作 是位于 用户空间 中的 当 内核态 中任务完成准备返回 用户态 时检测到信号 递达并且此时为 用户自定义动作需要先切入 用户态 完成 用户自定义动作 的执行因为 用户自定义动作 和 待返回的函数 属于不同的 堆栈 空间它们之间也不存在 调用与被调用 的关系是两个 独立的执行流需要先坠入 内核态 通过 sigreturn() 坠入再返回 用户态 通过 sys_sigreturn() 返回 上述过程可以总结为下图 5.2sigaction  sigaction 也可以 用户自定义动作比 signal 功能更丰富 #include signal.hint sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);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 结构体信息 这个函数的主要看点是 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); //实时信号相关不用管 };其中部分字段不需要管因为那些是与 实时信号 相关的我们这里不讨论 重点可以看看 sa_mask 字段 sa_mask当信号在执行 用户自定义动作 时可以将部分信号进行屏蔽直到 用户自定义动作 执行完成 也就是说我们可以提前设置一批 待阻塞 的 屏蔽信号集当执行 signum 中的 用户自定义动作 时这些 屏蔽信号集 中的 信号 将会被 屏蔽避免干扰 用户自定义动作 的执行直到 用户自定义动作 执行完成 可以简单用一下 sigaction 函数 #include iostream #include cassert #include cstring #include signal.h #include unistd.husing namespace std;static void DisplayPending(const sigset_t pending) {// 打印 pending 表cout 当前进程的 pending 表为: ;int i 1;while (i 32){if (sigismember(pending, i))cout 1;elsecout 0;i;}cout endl; }static void handler(int signo) {cout signo 号信号确实递达了 endl;// 最终不退出进程int n 10;while (n--){// 获取进程的 未决信号集sigset_t pending;sigemptyset(pending);int ret sigpending(pending);assert(ret 0);(void)ret; // 欺骗编译器避免 release 模式中出错DisplayPending(pending);sleep(1);} }int main() {cout 当前进程: getpid() endl;//使用 sigaction 函数struct sigaction act, oldact;//初始化结构体memset(act, 0, sizeof(act));memset(oldact, 0, sizeof(oldact));//初始化 自定义动作act.sa_handler handler;//初始化 屏蔽信号集sigaddset(act.sa_mask, 3);sigaddset(act.sa_mask, 4);sigaddset(act.sa_mask, 5);//给 2号 信号注册自定义动作sigaction(2, act, oldact);// 死循环while (true);return 0; }当 2 号信号的循环结束10 秒3、4、5 信号的 阻塞 状态解除立即被 递达进程就被干掉了 注意 屏蔽信号集 sa_mask 中已屏蔽的信号在 用户自定义动作 执行完成后会自动解除 阻塞 状态 6 小结 截至目前信号 处理的所有过程已经全部学习完毕了 信号产生阶段有四种产生方式包括 键盘键入、系统调用、软件条件、硬件异常 信号保存阶段内核中存在三张表blcok 表、pending 表以及 handler 表信号在产生之后存储在 pending 表中 信号处理阶段信号在 内核态 切换回 用户态 时才会被处理
http://www.zqtcl.cn/news/993017/

相关文章:

  • 福州网站建设服务平台今天发生的重大新闻
  • 招聘信息网搜索引擎优化代理
  • 免费的企业网站cms纯文字logo在线制作
  • 深圳电器公司官网网站建设 网站优化
  • 大连 网站建设昆明建设网站哪家好
  • 网站首页设计及运行效果网站建设与管理任务分工
  • 自己建设论坛网站家用电脑搭建服务器
  • 做网站上海公司企业网站内页
  • 手机网站seo山东网站建设网
  • 溧阳 招网站开发wordpress 占内存
  • 网站seo 工具做网站建设公司排名
  • 丹阳网站建设企业建设网站管理制度
  • 怎样审请网站集成装修全屋定制
  • 好看响应式网站模板下载可以访问的国外网站
  • 做电脑网站宽度网站建立安全连接失败
  • 西安网站设计哪家公司好my12777域名查询
  • 西宁网站建设排名网站设计对网站建设有哪些意义?
  • 北京平台网站建设价位怎样做网站卖网站
  • 网站建设与维护试题a卷建设银行官方网站买五粮液酒
  • 安装网站源码做文艺文创产品的网站
  • 软件公司网站设计与制作电子商务成功网站的案例
  • 购物车功能网站怎么做的建设众筹类网站
  • 哪些网站做的美爱站工具网
  • 对网站开发的理解源码资源网
  • 有哪些做兼职的网站网站建设的项目计划书
  • 如何做行业网站江苏城乡建设部网站首页
  • 淘客网站怎么做 知乎wordpress 删除插件
  • 深圳市住房和建设局人事调整公司网站seo怎么做
  • 小型影视网站源码好看的个人博客
  • 哈密建设厅网站西安培训机构