zoukankan      html  css  js  c++  java
  • 第40天-捕捉信号(2013.09.13)

      1.如果信号的处理动作是用户自定义函数, 在信号递达时就调用这个函数, 这称为捕捉信号

            1.用户程序注册了SIGQUIT信号的处理函数sighandler。

            2.当前正在执行 main函数, 这时发生中断或异常切换到内核

            3.在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达

            4.内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数,sighandler和 main函数使用不同的堆栈空间, 它们之间不存在调用和被调用的关系, 是两个独立的控制流程

            5.sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态

            6.如果么有新的信号递达,这次再返回用户态就是回复main函数的上下文继续执行了

      2.sigaction

            函数原型 ; #include <signal.h>

                  int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

            作用 ; sigaction函数可以读取和修改与指定信号相关联的处理动作。

               返回值 ; 成功返回0, 出错返回 -1

                signo : 指定的信号的编号。

                若act指针非空, 则根据act修改该信号的处理动作。

                若oact指针非空,则通过oact传出该信号原来的处理动作。

                act 和 oact 指向sigaction结构体

                    struct sigaction {

                           void (*sa_handler)(int);    //  信号处理函数

                           sigset_t sa_mask;       //  临时信号屏蔽字

                           int sa_flags;          //  解释在下面

                           voi (*sa_sigaction)(int , siginfo_t *, void *);  // 带参数的信号处理函数

                          };

                       当 sa_flags = 0时, 调用信号处理函数。

                       当sa_flags = SA_SIGINFO 时, 使用带参数的信号处理函数

                       将sa_handler赋值位常数 : SIG_IGN      表示忽略信号

                              赋值为 : SIG_DFL        表示执行系统默认动作

      3.pause    使调用进程挂起直到信号递达

          函数原型 : #include <unistd.h>

                int pause(void);

          若信号的处理动作是终止进程则进程终止, 么有机会返回

          若信号的处理动作是忽略,则进程继续处于挂起状态,不返回

          若信号的处理动作是捕捉, 则调用了信号处理函数后, 返回-1.error设置为 EINTR

              pause只有出错的返回值。    EINIT 表示“信号被中断”

      4.一般情况下, 调用信号处理函数时,信号自动屏蔽。

      5.注意 : 信号处理函数不可不注册, 不注册的话,会按照默认方式处理 : 结束进程

      6.不可重入 :

            1.使用全局或静态变量

            2.不使用标准输入和标准输出

            3.不使用临界区变量

      7. 如果一个函数符合以下条件之一则是不可重入的 : 

            调用了malloc或free, 因为maloc也是用全局链表来管理堆的

            调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构

      8.sig_atomic_t 类型 : 原子类型

        volatile限定符

            volatile限定 :

                变量的内存单元中的数据不需要写操作就可以自己发生变化,每次读上来的值都可能不一样

                即使多次向变量的内存单元中写数据,只写不读也并不是在做无用功,而是有特殊意义的

          sig_aomic_t类型的变量应该总是加上volatile限定符

      9.竟态条件与 sigsuspend函数

        竟态条件 : 如果我们写程序时考虑不周密,就可能由于时序问题而导致错误

        函数原型 : #include <signal.h>

              int sigsuspend(const sigset_t * sigmask);

  • 相关阅读:
    Unity3D读取assetbundle
    Unity3D 发布成exe之后黑屏
    Unity3D优化总结
    Unity3D中中 rect[2] == rt->GetGLWidth() && rect[3] == rt->GetGLHeight()错误的原因及解决方法
    C# mysql 插入数据,中文乱码的解决方法
    WPF Canvas做自动缩放时获取控件的实际高度
    面向对象
    常用模块介绍
    python异常处理,多线程,多进程
    python生成器,递归调用
  • 原文地址:https://www.cnblogs.com/cxw825873709/p/3324718.html
Copyright © 2011-2022 走看看