进程间信号:
信号更多的是通知事件的发生,信号产生之后第一时间也不是直接处理而是先存储下来,处理信号 信号的产生-》信号的注册-》(信号的阻塞)-》信号注销-》信号处理
Linux先有62种信号使用 kiil-l 查看
信号分两类:1-31不可靠信号 34-64可靠信号(实时信号)
产生:
1.通过硬件中断产生 ctrl + c
2.程序异常 SIGFPG SIGSEGV unix环境高级编程
3.软件条件产生
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
int main()
{
//int kill(pid_t pid, int sig);
// 向指定进程发送指定信号
//kill(getpid(), SIGINT);
//int raise(int sig);
// 向自身发送信号
//raise(SIGTERM);
//void abort(void);
// 向自身发送SIGABRT信号
//alarm(3);
// 在n秒之后向进程发送SIGALRM信号
// 设置一个定时器,取消上一个定时器,并且返回上一个定时器剩余时间
while(1) {
printf("-------\n");
sleep(1);
}
return 0;
}
核心转储(core dump)
保存当前程序运行的数据以及调用栈信息,用于错误原因定位调试。
如果程序运行错误,可以直接通过core文件来gdb调试(有些错误可能是偶然发生)
coredump默认关闭:隐私安全/资源占用
coredump打开: ulimit -c 1024
注册:
信号的注册/给一个进程发送信号,就是修改这个进程pcb种关于的pending位图,将相应的信号位置1
阻塞:信号的递达:信号的处理
暂时不处理信号(阻止信号的递达),并不是不接受信号。
要阻塞一个信号,那么就修改pcb种关于信号的block位图,将相应的信置1,这个位图就像一个备注,说明如果接受到这个信号暂时不处理
信号未决:这是一种状态,信号从注册成功到信号递达之间的一种状态
sigprocmask()
有两种信号是不会阻塞的:SIGKILL SIGSTOP
sigpending 获取信号
注销:
就是从pending集合中将即将要处理的信号相应位置0(从pcb的pending集合中移除)
可靠信号注册就是将相应pending位图置1,然后添加一个sigqueue结构到链表中,
之后如果有相同信号来,一看位图已经置1了,就不做操作了,意味着后来的信号在前一个信号未处理之前不会重复注册,代表丢了!!
可靠信号就是不管有没有注册都要置1,并且添加节点到链表中去,所以不会丢信号
/* 这是一个演示信号阻塞的demo
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main()
{
//我要阻塞这个集合中的信号
sigset_t new_block;
//用于保存原来阻塞集合中的信号,防止后续要将阻塞集合还原回去
sigset_t old_block;
//int sigemptyset(sigset_t *set);
// 清空一个信号集合
sigemptyset(&new_block);
//int sigfillset(sigset_t *set);
// 将所有的信号都添加到set集合中
//int sigaddset(sigset_t *set, int signum);
// 添加指定的单个信号到set集合中
//int sigdelset(sigset_t *set, int signum);
// 从集合中移除一个指定的信号
//int sigismember(const sigset_t *set, int signum);
// 判断一个信号是否在一个集合中
sigfillset(&new_block);
//int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
// 阻塞信号/解除阻塞
// how:
// SIG_BLOCK 阻塞集合中的信号
// SIG_UNBLOCK 对集合中的信号解除则色
// SIG_SETMASK 将集合中的信号设置到阻塞集合中
// set: 要阻塞/解除阻塞的集合
// oldset:保存原先阻塞集合中的信号
sigprocmask(SIG_BLOCK, &new_block, &old_block);
//不按回车就不往下走
getchar();
sigset_t pending;
sigemptyset(&pending);
//获取当前未决信号
sigpending(&pending);
if (sigismember(&pending, SIGINT)) {
printf("SIGINT is blocked!!\n");
}
//解除阻塞
sigprocmask(SIG_UNBLOCK, &new_block, NULL);
//将原先阻塞集合中的信号还原回去
sigprocmask(SIG_SETMASK, &old_block, NULL);
return 0;
}
非可靠信号注销就是删除链表节点,相应位图置0
可靠信号注销是删除节点,判断