企业宣传注册哪些论坛 网站好,中国百强县市榜单,网页制作基础教程图片,南京网站设计是什么8. 阻塞信号
(一)信号其他相关常见概念
实际执行信号的处理动作称为信号递达(Delivery)信号从产生到递达之间的状态,称为信号未决(Pending)进程可以选择阻塞 (Block )某个信号被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作(即被阻塞的信…
8. 阻塞信号
(一)信号其他相关常见概念
实际执行信号的处理动作称为信号递达(Delivery)信号从产生到递达之间的状态,称为信号未决(Pending)进程可以选择阻塞 (Block )某个信号被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作(即被阻塞的信号进程是不会对其进行处理动作 注意:
阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里 二sigset_t
从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的
因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号 的“有效”或“无效”状态
在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有
效”和“无效”的含义是该信号是否处于未决状态 三信号集操作函数 #include signal.h int sigemptyset(sigset_t *set); 清空set即位图清空成0 int sigfillset(sigset_t *set); 填满set(即位图上的32个比特位全是1 int sigaddset (sigset_t *set, int signo); 设置set用位图表示的对应信号即变成1 int sigdelset(sigset_t *set, int signo); 取消set用位图表示的对应信号即变成0 int sigismemberconst sigset_t *set, int signo); 判断set用位图表示的对应信号是否被设置如果被设置则返回1如果没有则返回0 注意
在使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的状态除了sigismember函数其它四个函数都是成功返回0,出错返回-1sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1 四sigprocmask 函数
调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集) #include signal.h int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 参数 how 参数一般有三个选项 oset 参数保存了上一次的阻塞信号集 返回值:若成功则为0,若出错则为-1 五sigpending 函数
读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1 #include signal.h sigpending (const sigset_t *set 使用 信号操作集函数sigprocmask 函数sigpending 函数 9. 捕捉信号
一捕捉信号的时机
当我们的进程从内核态返回到用户态的时候进行信号的检测和处理 内核态
允许进程访问内核区的数据和代码
用户态
只允许进程访问自己用户区的数据和代码 注意
对于进程来说调用操作系统的方法就是在进程地址空间中内核区找到对应的方法操作系统的本质基于时钟中断的死循环操作系统也是一个进程管理着各种软硬件但同时它其实也是需要别人推进执行计算机硬件中有一个时钟芯片每隔很短的一段时间向计算机发送时钟中断 二信号捕捉的过程 三sigaction 函数
sigaction函数可以读取和修改与指定信号相关联的处理动作 #include signal.h int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); 返回值调用成功则返回0,出错则返回- 1 注意
若act指针非空,则根据act修改该信号的处理动作若oact指针非空,则通过oact传出该信号原来的处理动作
act和oact指向sigaction结构体: 结构体中有 sa_handle 类型的变量 和 sa_mask变量 sigaction 函数 代码 注意
pending位图从1-0的变化是在执行捕捉方法之前先清0再调用信号被处理的时候对应的信号也会被添加到block表中比如2号信号正在执行对应的处理动作当此时还收到2号信号时2号信号此时被设置成阻塞信息也可以通过sigaction结构体中的sa_mask变量设置对应的阻塞信号集防止信号捕捉被嵌套调用 10. 可重入函数
如果一个函数被重复进入的情况下可能会出错则它是不可重入函数否则是可重入函数比如链表的插入如果有两个流都用同一个插入函数执行同一个链表可能会在插入时发生进程切换导致一个流的插入函数没有执行完就进行下一个流的插入导致内存发生泄漏 如果一个函数符合以下条件之一则是不可重入的:
调用了malloc或free,因为malloc也是用全局链表来管理堆的调用了标准I/O库函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构 11. volatile 关键字
volatile 作用保持内存的可见性即CPU 可以从内存读取数据防止编译器过度优化 12. SIGCHLD信号
子进程在终止时会给父进程发SIGCHLD信号17号信号,该信号的默认处理动作是忽略,父进程在信号处理函数中调用wait清理子进程即可
要想不产生僵尸进程还有另外一种办法:父进程调用sigaction将SIGCHLD的处理动作设置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不 会产生僵尸进程,也不会通知父进程 注意
系统默认的忽略动作和用户用sigaction函数自定义的忽略 通常是没有区别的,但这是一个特例后一种方法对于Linux可用,但不保证在其它UNIX系统上都可用