1、虚拟地址空间划分
- 每个进程都有自己虚拟地址空间
- 为了保障系统运行的安全,虚拟地址空间被划分为用户空间和内核空间
- 操作系统运行在内核空间,用户程序运行在用户空间,内核空间由所有进程地址共享,但是用户程序不能直接访问内核空间
2、线程
- 操作系统的进程控制信息是保存在内核空间的,里边有页目录、进程ID、打开文件句柄等信息
- 线程就是进程中的执行体,有指定的执行入口(通常是某个函数的入口)
- 线程执行时要使用从进程虚拟地址空间中分配的栈空间来存储数据
- 在创建线程时,操作系统会使用用户空间和内核空间分别分配用户栈和内核栈
- 线程切换到内核态执行时会使用内核栈,目的是为了不允许用户代码对它进行修改
- 操作系统会记录每个线程的控制信息,如线程栈、线程入口、线程ID等等
- 在Windows中线程控制信息对应TCB
- 在Linux中对应task_struct结构体
- 在PCB中可以找到进程拥有的线程列表
- 同一个进程内的线程可以共享进程的控制信息,如进程ID、句柄表等
3、线程执行
- 当执行进程中某个线程时,CPU的指令指针会指向线程的执行入口,栈基和栈指针寄存器会记录线程的用户栈空位置
- CPU执行程序时,面向的是某个线程,所以线程是操作系统调度与执行的基本单位
- 一个进程中至少要有一个线程,从某个开始执行的线程称为主线程,它是由父进程或操作系统创建的
- 进程中的其他线程一般都是由主线程创建的
- 线程中发生函数调用时就会分配函数调用栈
- 虚拟内存分配、文件操作、网络读写等都是由操作系统来实现的
4、系统服务
- 当线程调用操作系统提供的系统服务,需要进行系统调用
- CPU中会有一个标志用于记录当前程序是用户态还是内核态
- 当发生系统调用时,CPU就会切换到内核态,就能使用内核空间的内核栈,使用内核的系统函数
- 最初系统调用是通过软中断触发的(通过指令模拟中断),与其对应的就是硬件中断,操作系统会记录各种中断信息(如x86的sysenter和amd64的syscall),等系统调用结束后会利用之前保存的信息恢复到用户线程的执行现场
5、线程切换
- 只有获得CPU时间片的程序才能运行,由于时间片很短,用户感觉不到程序的切换过程
- CPU执行的很快,在很短的时间内足够执行很多很多的指令
- 某个线程获得的时间片用完时,CPU硬件时钟会触发中断,会执行下一个准备就绪的线程
- 同一个进程的线程间切换
- 不同进程的线程切换