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