异常和中断以及fork()的用法
一.关于异常和中断的零散知识点
1.有256种不同类型的异常和中断
2.异常可以分为四类:中断,陷阱,故障和终止
3.x86系统系统启动后首先在实地模式下工作,结束后进入保护模式
实地模式下,用中断向量表描述,中断向量表固定在0~3FFH的内存区域,中断向量地址为中断类型号乘以4,每个中断向量占4个字节,由16位段地址和16位段内偏移量组成,通过对段地址左移4位然后加上段内偏移量,以得到20位的中断服务程序首地址
保护模式下,用中断描述符表描述,通过专门的中断描述表来获得中断服务程序或异常处理程序的入口地址
4.IA-32保护模式下iret指令执行过程中,会检查异常/中断响应前、后是否处于同一特权级,若处于同一特权级,则不需要从内核栈中弹出用户栈指针SS/ESP,因为,在这种情况下,异常/中断响应式并没有在内核中保存用户栈栈顶指针
5.IA-32保护模式下异常和中断响应过程中,处理器根据类型号i访问IDTi,再根据IDTi中的段选择符访问指定段描述符,处理结束前,CPU将对应IDTi中段选择符送CS,偏移地址送EIP,以便跳转到中断服务程序或异常处理程序执行
二、fork()的用法
父进程通过调用fork()函数创建一个新的运行的子进程,子进程得到与父进程用户级虚拟地址空间相同的一份副本,包括代码和数据段、堆、共享库以及用户栈,但父进程与子进程之间是相互独立的。最为重要的是,fork()函数一次调用,两次返回`
int main()
{
pid_t pid;
int x=1;
pid=Fork();
if(pid==0){
printf("child:x=%d\n",++x);
exit(0);
}
printf("parent:x=%d\n",--x);
exit(0);
}
根据fork()的用法即输出
parent:x=0
child:x=2
因为子进程父进程共享数据,所以在子进程和父进程中x都等于1
再来一个例子
#include"stdio.h"
#include"stdlib.h"
int main(){
int i;
for(i=0;i<2;i++)
Fork();
printf("hello\n");
exit(0);
}
即输出
Hello
Hello
Hello
Hello
再来一例呀!
void doit()
{
if(fork()==0){
fork();
printf("hello\n");
exit(0);
}
return;
}
int main(){
doit();
printf("hello\n"0;
exit(0);
}
在这个代码中,根据fork()的一次调用,两次返回,调用第一个fork()应该会有两个进程,但是由于在子进程中fork()返回零,所以只有一个进程能进入if语句里,再调用第二个fork(),产生两个进程,及再doit()函数里会输出两个hello,在main()函数里输出一个hello
则输出
hello
hello
hello