1. signal
    1. #define SIG_ERR (void (*)())-1
    2. #define SIG_DFL (void (*)())0
    3. #define SIG_IGN (void (*)())1
  2. 阻塞和未决(到达或忽略)标志位
  3. 改变信号屏蔽字
    1. #include <signal.h>
    2. int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
    3. 信号操作集
      1. set为需要设置的信号集,通过sigaddset加入,oset有指向就把原来的信号屏蔽字储存
      2. #include <signal.h>
      3. int sigemptyset(sigset_t *set);
      4. int sigfillset(sigset_t *set);
      5. int sigaddset(sigset_t *set, int signo);
      6. int sigdelset(sigset_t *set, int signo);
      7. int sigismember(const sigset_t *set, int signo);
  4. 自由主题
    1. struct sigaction {
    2. void (*sa_handler)(int);可以为SIGIGN ,sigdef,也可以自己注册一个函数,被系统调用
    3. sigset_t sa_mask; 通过signadd自己添加的额外需要屏蔽的信号,捕捉的信号处理完可以恢复元屏蔽位
    4. int sa_flags; /* signal options, Figure 10.16 */
    5. void (*sa_sigaction)(int, siginfo_t *, void *);
  5. 原子操作,防止错乱
    1. 一此步骤完成,原子操作。
    2. 序要求严格
    3. volatile sig_atomic_t
      1. 多流程控制时,编译器优化单一流程没有改变a值,就不需要重复读取(不知道外部还有),因此原子操作时应该加上volatile,防止优化
  6. 信号状态
    1. kill -l可以列出信号类型
    2. 接受后保存在进程的PCB中,内核首先读取这个,再觉得之后操作
      1. 产生方式:软件超时; 硬件异常;终端接受键盘命令;kill;
  7. 信号控制
    1. 信号处理,和用户进程异步,不在同处理堆
    2. 处理方式:忽略; 默认; sigaction返用户态,称 catch;
    3. 阻塞
      1. 取消阻塞后称递达
      2. 阻塞前未决,信号产生未决标志位就会变为1表示信号正在被阻塞,后者依靠前者
        1. 未决和阻塞标志可以用相同的数据类型sigset_t,
          1. #include <signal.h> int sigpending(sigset_t *set);
          2. 读取未决信号集,返回状态
  8. 捕捉信号
    1. 进行下一步动作
    2. int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
      1. oact是旧结构体
    3. pause处理,挂起至信号抵达,信号处于忽略状态。继续挂起,只如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,errno设置为EINTR,在程序中作用之所查看是否有其他中断信号
  9. 重入操作
    1. 函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入
    2. 大多不可重入的,调用了malloc或free,因为malloc也是用全局链表来管理堆的。 调用了标准I/O库函数。
  10. 竞态条件
    1. int sigsuspend(const sigset_t *sigmask);errno
      1. 挂起和解除屏蔽同时进行,信号屏蔽字由sigmask参数指定(蔽or不弊),SIGALRM递达后suspend返回,自动恢复原来的屏蔽字,之后要手动还原