一、系统调用
1、文件描述符:每个进程在PCB中都保存着一份文件描述表,文件描述符即为该表的索引;
内核利用文件描述符来访问文件,当打开/读/写一个文件时,内核就会返回一个文件 描述符;//文件描述符是一个非父负整数;
2、系统调用:
(1) 实现在内核中,通过接口来接受,而不是通过调用,让代码在内核中执行,即内核代表用户来执行;
(2)用户态: 程序运行的环境在用户时,执行用户代码
内核态: 程序运行在内核(优先级较高,权限不同)
系统调用号:系统调用表的下标#define _NR fork 2 /绝对值
系统调用表:通过汇编代码实现,每个调用号所对应的是函数的入口地址
(3)当一个进程运行时都会打开三个文件:stdin(标准输入).stdout.(标准输出),(标准错误输出)
3、系统调用和库函数的区别
系统调用的实现在内核中,通过接口来接受//系统调用是进入内核的桥梁
库函数的实现在库函数中,直接跳到进程地址执行,不是操作系统的一部分,
二、信号
1、信号:发送信号kill()//属于系统调用;
子进程结束,发送给父进程信号:SIGCHLD(子进程中断或者改变状态),父进程不进行任何处理(利用他可以解决僵尸进程)
2、收到信号做出响应signal();
(1)默认
(2)忽略
(3)自定义
补充:15 kill 命令默认发送
9 不能通过signal()改变响应方式,只能按默认结束进程
Ctrcl + c 结束在前台运行的程序 -> 发送2 终端中断
3、信号的接受和程序的执行 是异步的执行,何时收到信号,进程并不能确定
4、信号的实现:
在内核中有俩个变量:
Kill 发送信号就是将每个长整型的某个位从0置为1,当内核发现某个位变为1,这说明收到了相应的信号,查找该信号对应的处理方法(void fun(int sign)),调用该方法响应信号
程序突然崩掉或者异常结束,是因为内核收到信号的原因
5.进程结束的俩种可能性:
(1)程序主动调用exit结束;
(2)收到异常结束信号;