个人主页:Lei宝啊
愿所有美好如期而遇
目录
问题一:操作系统怎么知道键盘按键被按下,然后去读取字符或者控制命令(ctrl+c等)?
问题二:信号产生后写入task_struct中,但是task_struct是内核数据结构,用户可以写吗?
信号是什么?
信号是Linux提供的使用户(进程)给其他进程发送异步信息的一种方式。
我们可以先给出这样几个结论:
- 在信号还没有发送给当前进程时,当前进程已经知道当一个信号发送过来时,该如何处理这个信号
- 信号应该被提前设置好,而进程中有识别信号的方式,直到如何进行处理。
- 信号在发送过来时,如果进程在执行重要的代码时,信号应当进行临时保存。
- 信号到来时,不一定要立即处理。
- 信号的产生是随机的,我们无法准确预测信号何时发送过来,所以信号是异步发送的。
- 同步:在同步操作中,一个任务需要等待前一个任务完成后才能开始,也就是说,任务必须按照某种顺序一步一步来执行,后一个任务依赖前一个任务的结果
- 异步:在异步操作中,任务可以不必等待前一个任务完成就立即开始,异步操作不依赖于之前任务是否完成,只是简单地启动任务,然后让操作系统在后台处理任务,它不会阻塞程序的后续执行
因为我们不知道信号是何时发送的,并且信号的发送并不依赖于要给到信号的进程,所以信号的发送不必等待进程执行完一个任务,而是在进程执行过程中,进程执行他的,信号发送他的,各自做各自的事情,两者并发执行。
我们可以来看看常见的信号:
后面的信号这里剪掉了,他们是实时信号,我们要介绍的是分时操作系统,所以不对实时信号做解释。
信号的名字和编号都可以标识信号,他的名字就是宏,没有0号信号,也没有32,33号信号,对信号的学习涉及三个阶段:产生,保存,处理,本节我们着重介绍信号的产生。
简单介绍信号的处理方式:
- 默认动作,即默认设定的动作。
- 自定义动作,用户设定的动作。
- 忽略。
自定义动作通过signal系统调用实现:
用法我们在后面会谈到。
为什么要有信号?
因为系统要求进程能够有随时响应外部信号的能力,能够做出反应,停止或者终止等等。
信号是如何产生的?
kill命令
kill -9 pid 杀掉一个进程 (也可以kill -SIGKILL pid)
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;
int main()
{
while(true)
{
cout << "进程pid: " << getpid() << endl;
sleep(1);
}
return 0;
}
kill -2 pid 终止一个进程
键盘产生信号
比如ctrl + c, ctrl + \,都可以使一个进程退出,这里我们不卖关子,直接挑明,其实这两个控制命令会被解释成为信号,ctrl + c会被解释为2号信号,也就是终止一个进程,ctrl + \会被解释为3号信号,也是终止进程。
我们这里总是谈到几号信号可以终止进程,我们是怎么知道的?手册。
man 7 signal 一直往下翻就可以看到
我们还可以看到的同样是终止进程,但是他们的动作有Term和Core,其他信号的动作也有Stop,Ign(忽略),我们后面会着重谈到Term和Core的区别。
系统调用
kill系统调用
int