3.信号产生的方式
1.从键盘输入
在输入的时候,计算机怎么知道从键盘输入数据了呢?
键盘是通过硬件中断的方式,通知系统键盘已经按下了
CPU存在很多针脚,有自己的编号,接到主板上
键盘是通过中断控制器(如8259)连接到CPU的,
当按键盘中的某个位置时,操作系统要知道是哪个设备按下的(磁盘 键盘 网卡)
键盘通过中断控制器链接到9号阵脚处,触发中断
而从这个阵脚的数字被叫做 中断号
CPU内部有各种寄存器,当阵脚有数字时已经就绪时,向CPU寄存器的内部写数字
就完成了硬件中断
操作系统内维护一张中断向量表
中断向量表内部包含函数指针
中断号作为中断向量表的下标,直接调用中断向量表中对应的方法
而这个方法会从键盘中读取数据
2.使用系统调用向进程发送信号
kill
输入 man 2 kill
指令
第一个参数为目标进程
第二个参数为信号
向目标进程(pid)发送对应的信号(sig)
成功返回0,失败返回-1
命令行参数
main函数的两个参数,char* argv[] 为指针数组 ,argv为一张表,包含一个个指针,指针指向字符串
int argc,argc为数组的元素个数
创建mykill.cc文件
当输入./mykill时,由于有命令行参数的存在,将其放入数组下标为0的位置中,同时数组个数为0
所以进入自定义的用户手册
修改mykill.cc文件内容
c由于agrv是字符指针数组,而我们想要的目标进程和信号编号都是数字,所以需要使用atoi函数,将字符串转化为整数
创建loop.cc文件
运行loop.cc与mykill.cc文件,形成可执行程序
在终端1中运行loop
在终端2中运行输入 ./mykill 9 对应进程的pid值
9为进程编号 pid值为目标进程
输入loop进程的pid值,从而使用9号信号结束loop进程
raise
输入 man raise
指令
谁调用raise,就给谁发指定的信号
修改mykill.cc文件内容
再去调用可执行程序mykill时,自己就结束了,因为自己给自己发送2号信号
abort
输入 man abort
指令
给自己发信号
再次修改mykill.cc文件内容
没有end存在,说明当前进程自己把自己干掉了
通过添加signal的方式,若运行mykill,自动生成get a signal :6
说明使用 Aborted时使用6号信号
而在实际运行时,会自动生成get a signal :6 ,说明实际上Aborted是使用6号信号
3.由软件条件产生信号
alarm函数可以设定一个未来时间
如:alarm(5) alarm函数调用完了,5秒后给当前进程发送SIGALRM(14)信号,该信号的默认动作是终止当前进程
alarm函数返回值是0或者以前设定的时间还余下的秒数
假设你想睡一觉,设定闹钟30分钟后响,但是在20分钟后你被吵醒了,你又重新设置闹钟15分钟后响
此时返回值就是上一次余下的10分钟
修改mykill.cc文件内容
计算1S中计算机会将整数累计到多少
在这次计算中,count只有11万多,非常不符合我们的预期
因为要打印到显示器上,以及网络问题,非常拖延速度
修改count为全局变量,在发送信号时,自定义方法中输出count值
这时count的值就变成5亿多
两者相比之下,说明IO效率非常底下