进程信号:
信号介绍:
生命周期:信号产生,信号在进程中注册,信号在进程中注销,信号处理
信号的阻塞
竞态条件
可重入/不可重入函数
信号介绍:软件中断,通知进程中发生了某个事件,打断进程当前的阻塞,去处理这个事件
信号有很多种类—每个信号都代表一个事件(操作系统识别这些信号)
信号有自己的生命周期:信号的产生—>进程的注册—>进程的注销—>处理
信号种类:
kill -l查看信号种类:62种信号
非可靠信号:1~31(非实时信号)
可靠信号:34~64(实时信号)
信号的产生:
硬件:ctrl+c中断信号 / ctrl+l退出信号 / ctrl+z暂停信号
软件:kill -signo pid命令 / kill(pid,signo) / raise(signo) / abort() / alarm(sec)
//int kill(pid_t pid,int sig);
//给pid进程发送sig信号
//kill(getpid(),SIGQUIT);
//int raise(int sig);
//给调用进程发送sig信号
//raise(SIGQUIT);
//void abort(void);
//给调用进程发送SIGABRT信号
//abort();
//unsigned int alarm(unsigned int seconds(;
//seconds秒之后,给调用进程发送SIGALRM信号
//seconds若为0,则表示取消上一个定时器
//返回值:上一个定时器的剩余时间
//alarm(3);
core dumped: 核心转储 当进程异常退出时,保存进程运行信息
ulimit -a 查看
ulimit -c 设置core文件最大大小 单位是kb ulimit -c 1024
gdb ./main ->core-file core.pid ->bt
信号在进程中注册:
在pcb的struct sigpending->signal(位图)中标记收到了哪些信号;并且为这个信号组织一个sigqueue节点,添加到链表中
sgiset_t——>数组—作为二进制比特位位图使用—标记信号是否到来
未决信号: 暂时没有被处理的信号,未决指的是信号从产生到被处理之间所处的状态
可靠信号: 34~64 修改位图为1,并且为每个到来的信号都添加一个sigqueue节点,保存信号信息
非可靠信号: 1~31 判断位图是否为1,为1则什么都不做(信号/事件丢失);否则添加节点修改位图
信号的注销:
在处理信号之前,在pcb中抹除信号存在的痕迹—删除节点,修改位图置0
可靠信号: 删除节点后判断是否还有相同节点,若有,位图置1,没有则置0
非可靠信号: 删除节点后,位图置0(因为非可靠信号节点只会有一个)
信号的处理:信号的递达
默认处理 | 操作系统中既定义好的信号处理方式 |
---|---|
忽略处理 | 忽略,什么都不做 |
自定义处理 | 用户自己定义处理方式 |
signal函数: | 存在内核版本差异性(慎用) |
sigaction函数 |
handler:信号处理方式
SIG_DFL 默认处理方式
SIG_IGN 忽略处理方式
typedef void(*sighandler_t)(int); 用户自定义信号回调函数类型
自定义处理方式信号的捕捉流程:
一个进程因为系统调用/中断/异常从用户态切换到内核态运行,完成功能后,准备返回用户态的时候,查看是否有信号待处理,如果有,并且是默认/忽略处理方式,则在内核直接完成,若是自定义处理方式,则返回用户态调用信号处理函数,完毕之后调用sigreturn返回内核态,当没有信号哦待处理,则调用sys_return返回用户态主控流程
信号的阻塞:阻止信号被递达
阻塞:独立于生命周期之外,用户可以设置哪些信号注册后,暂时不处理
在pcb中有个block信号阻塞集合,这个信号阻塞集合的作用就是用于标记,哪些信号到来的时候暂时不被处理,用户阻塞哪些信号就是在这个位图中做标记
sigpromask(how,sigset_t new,old)
SIG_BLOCK SIG_UNBLOCK SIG_SETMASK
sigemptyset sigfillsetP sigaddsetP sigdelset sigismember sigpending
在所有信号中有两个信号:SIGKILL -9 SIGSTOP -19无法被阻塞,无法被自定义,无法被忽略
竞态条件:多个运行时序的竞争执行
可重入/不可重入函数:
函数是否可以在多个执行流中重复进入(调用),而不会出现异常问题;
若有可能出现问题就是不可重入函数;否则就是可重入函数
函数可重入与不可重入的关键点:是否在函数中对全局函数进行非原子操作
当用户自己设计函数或者调用别人函数的时候就需要考虑函数是否可重入
malloc/free不可重入函数–课后调研–动态内存管理
关键字:volatile–保持内存可见性–防止编译器过度优化—被volatile关键字修饰的变量每次使用时都要重新从内存中获取数据
SIGCHLD信号:
操作系统通过SIGCHLD信号通知父进程,有子进程退出
但是在操作系统中SIGCHLD信号的处理方式默认时忽略处理
sigcb(signo)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}