信号的概念和机制

news/发布时间2024/5/15 9:05:31

1.信号的概念和机制

理解信号可以参考生活中,烽火、狼烟等

信号的特点:1.简单;2.不能携带大量信息;3.满足某个特设条件才发送

1.1.信号的机制

信号时软件层面的“中断”,信号VS中断VS异常,三个概念可以一起学习

每个进程收到的所有信号,都是由内核负责发送、内核处理的

简单地说,unix的信号机制,是一种软中断

1.2.与信号相关的概念

1.2.1.信号产生

  1. 按键,如:Ctrl + c、Ctrl + z、Ctrl + \
  2. 系统调用,如:kill raise abort
  3. 软件条件,如:定时器alarm
  4. 硬件异常,如:非法访问内存(段错误)、除0(浮点数例外)、内存对齐出错(总线错误)
  5. 命令产生,如:kill

1.2.2.信号的状态

image

  1. 信号产生/发送
  2. 未决
  3. 递达

1.2.3.信号的处理方式

  1. 执行默认工作(大部分信号时终止当前进程)
  2. 忽略(丢弃)
  3. 捕捉(执行用户处理函数)

1.3.信号屏蔽字与未决信号集

linux内核的进程控制块PCB是一个结构体,处理包含进程id、状态、工作目录、用户id、文件描述符表等,

还包括了信号相关的信息,主要是信号屏蔽字和未决信号集(本质是bitmap)

  • 信号屏蔽字(阻塞信号集):将某些信号加入集合,对他们设置屏蔽,当屏蔽x信号后,再收到x信号,x信号的处理将推后(解决屏蔽后)
  • 未决信号集:
    1. 信号产生,未决信号集中描述该信号的位立刻翻转为1,表示该信号处于未决状态。当信号被处理对应位翻转为0。这一时刻往往非常短暂
    2. 信号产生后由于某些原因(一般是阻塞)不能递达。这类信号的集合称为未决信号集。在屏蔽解除前,信号一直处于未决状态

image

1.4.信号四要素与常见信号

1.4.1.信号四要素

man 7 signal查看

  1. 编号

  2. 名称(不重要,代码开发中使用信号对应的宏)

  3. 事件(产生信号的事件)

  4. 默认处理动作

image

1.4.1.常见信号

linux终端输入:kill -l

  • 1-31信号:常规信号,有默认事件和处理动作

  • 34-64:实时信号,没有默认事件

 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

1.5.kill函数和kill命令

  • kill是发送一个信号给进程

man kill-->命令

man 2 kill-->函数

image

  • kill的第二个入参pid,传不同的值有不同的作用:

image

  • 一个例子
int main(int argc, char *argv[])
{pid_t pid = fork();if (pid > 0) {while (1) {printf("parent pid = %d\n", getpid());sleep(1);}} else if (pid == 0) {printf("******child pid = %d, ppid = %d\n", getpid(), getppid());sleep(2);printf("******child process will kill parent process = %d, ... ...\n", getppid());sleep(1);kill(getppid(), SIGKILL); // SIGKILL 默认动作:终止进程// kill(getppid(), SIGCHLD); // SIGCHLD 子进程状态发送变化给父进程发送该信号,默认进程:忽略该信号}return 0;
}
  • 其他发信号函数

    int raise(int sig);

    void abort(void);

1.6.两个闹钟(定时器)函数

1.6.1.alarm函数—自然定时

设置定时器(闹钟)。在指定seconds后,内核会给当前进程发送14) SIGALRM信号。进程收到该信号,默认动作终止进程。

每个进程有且仅有一个定时器。

image

  • 常用:取消定时器alarm(0),返回定时器剩余秒数
int main(int argc, char *argv[])
{int cnt = 0;alarm(1); // 1秒后发送14) SIGALRM信号。进程收到该信号,默认动作终止进程while (1) {cnt++;printf("%d\n", cnt);}return 0;
}
  • 利用time指令执行程序:time a.out,发现:

    real > (user + sys),其中等待时间是由于printf调用write系统调用(进行标准输出),进行IO操作,比较耗时(程序运行的瓶颈在于IO)

real:程序实际运行时间

user:用户态时间

sys:内核态时间

image

  • 如果把IO到终端的打印重定向,time a.out > out,看看时间,1秒钟的计数:

image

1秒的计数值比之前大了很多很多:

image

1.6.2.setitimer

代替alarm,时间精度更高

image

1.7.信号集操作函数

1.7.1.set增删改查

自定义一个sigset_t类型的set(bitmap),信号集操作函数,对bitmap进行增删改查

image

1.7.2.sigprocmask函数——屏蔽信号、解除屏蔽

sigprocmask() is used to fetch and/or change the signal mask of the calling thread.

注意:屏蔽信号只是将信号处理延后执行(延至解除屏蔽);而忽略表示将信号丢弃处理

image

how的取值:

  • SIG_BLOCK:阻塞

  • SIG_UNBLOCK:解除阻塞

  • SIG_SETMASK:覆盖

1.7.3.sigpending函数——读取进程的未决信号集

image

1.7.4.信号集操作函数使用原理分析

自定义信号集set,去操作信号屏蔽字,进而影响未决信号集

  • set增删改查 函数—>sigprocmask 屏蔽或解除屏蔽

1.7.5.一个例子

void PrintSet(const sigset_t *set)
{int i;// 打印【1-32信号】for (i = 1; i < 32; i++) {if (sigismember(set, i)) {putchar('1');} else {putchar('0');}}printf("\n");
}int main(int argc, char *argv[])
{sigset_t set, oldset, pedset;// 操作自定义的信号集setsigemptyset(&set);sigaddset(&set, SIGINT);// 用自定义set,操作pcb中的信号屏蔽字sigprocmask(SIG_BLOCK, &set, &oldset);while (1) {// 读取未决信号集:前面对信号屏蔽字的SIGINT信号设置了阻塞,当SIGINT信号产生时,未决信号集SIGINT信号bit会置1,且不会恢复为0,直至SIGINT信号解除// 其他信号同理,处理不能被阻塞/屏蔽的信号sigpending(&pedset);// 循环打印未决信号集PrintSet(&pedset);sleep(1);}return 0;
}

1.8.信号捕捉

1.8.1.signal函数

简单了解,非posix标准,使用sigaction替代

image

1.8.2.sigaction函数

image

  • 重点关注结构体sigaction
struct sigaction {void     (*sa_handler)(int);							// 捕捉到x信号对应的回调函数void     (*sa_sigaction)(int, siginfo_t *, void *);		// 信号携带结构体等复杂参数sigset_t   sa_mask;										// 重点:区别于pcb中的信号屏蔽字;这里的sa_mask只工作与信号捕捉函数执行期间int        sa_flags;void     (*sa_restorer)(void);
};
  • sa_mask
sa_mask specifies a mask of signals which should be blocked (i.e., added to the signal mask of the thread in which
the signal handler is invoked) during execution of the signal handler.  In addition, the  signal  which  triggered
the handler will be blocked, unless the SA_NODEFER flag is used.翻译一下:
sa_mask指定在信号处理程序的执行期间应该被阻塞的信号的掩码(即,添加到调用信号处理程序所在线程的信号掩码)。此外,触发处理程序的信号将被阻止,除非使用SA_NODEFER标志。
  • 一个例子
void callback(int signum)
{if (signum == SIGINT) {printf("catch SIGINT signum=%d\n", signum);} else if (signum == SIGQUIT) {printf("catch SIGQUIT signum=%d\n", signum);}
}int main(int argc, char *argv[])
{struct sigaction act, old;act.sa_handler = callback;      // 设置信号捕捉到的回调函数sigemptyset(&act.sa_mask);      // 初始化sa_mask,sa_mask只在信号回调函数执行期间生效,目的是为了防止回调函数死循环act.sa_flags = 0;               // 默认传0sigaction(SIGINT, &act, &old);  // 注册SIGINT信号的捕捉函数sigaction(SIGQUIT, &act, &old); // 注册SIGQUIT信号的捕捉函数while (1);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/30481460.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

毕设

后台管理模块搭建完毕

自动驾驶运动规划:碰撞检测算法之分离轴定理

基于包围形的方法是一种粗略的碰撞检测方法,基于外接圆形的方法运算速度很快,但精度很差;基于轴对齐包围矩形(AABB)的方法适合本身就是矩形的物体,其运算速度非常快,但检测精度还是不够。运动规划:碰撞检测算法之分离轴定理附赠自动驾驶全套学习资料和量产经验:链接 如…

Oracle导出数据库与还原

导出部分 1.获取到Oracle directory目录与实际电脑目录的映射2.CMD导出Oracle数据库 DMP文件 //expdp 用户/密码@数据库监听地址 schemas=表空间名称 dumpfile=自定义名称.dmp directory=DATA_DIR(上面SQL中DIRECTORY_NAME 选择一个导出的文件就会在对应的DIRECTORY_PAT…

维吉尼亚密码

在一个凯撒密码中,字母表中的每一字母都会作一定的偏移,例如偏移量为3时,A就转换为了D、B转换为了E……而维吉尼亚密码则是由一些偏移量不同的恺撒密码组成。 为了生成密码,需要使用表格法。这一表格(如图1所示)包括了26行字母表,每一行都由前一行向左偏移一位得到。具体…

springboot学习

SpringBoot1 SpringBoot2 SpringBoot3 SpringBoot4 SpringBoot5 SpringBoot6 SpringBoot7 shiro 简介: 入门: 整合shiro 导包 写Controller 报错点击查看代码org.thymeleaf.exceptions.TemplateInputException: Error resolving template [index], template might not exist …

洛谷 P1656 炸铁路

题意:n个点,m条边,问有哪条边是去掉之后,会造成之前连通的点不再连通的?n <= 150, m <= 5000. 思路:连通算法有dfs+bool数组记录,或者dsu,感觉dsu更方便。m * n 不超过1e6,直接暴力。 class DisjointSet{ public:DisjointSet(int sz): sz_(sz){set_size_.assign…