实现线程包的方式
1. 在用户空间实现
内核对线程包一无所知,从内核角度考虑,就是按正常单线程进程管理。每个进程需要有其专用的线程表,用来跟踪该进程中的线程。这些表和内核中的进程表类似,不过仅仅记录各个线程的属性,如每个线程的程序计数器,堆栈指针、寄存器和状态等,并由运行时系统管理。
优点:
用户级线程包可以在不支持线程的操作系统上实现。线程切换比陷入内核要快一个数量级。因为如果某个线程阻塞,线程表保存该线程的寄存器,然后查看表中可运行的线程,并且把新线程的保存值重新装入机器的寄存器中。只要堆栈指针和程序计数器被切换,新的线程即可立即投入运行。如果机器有一条保存所有寄存器的指令和另一条装入全部寄存器的指令,那么切换可以在几条指令内完成。另外,保存线程状态的过程和调度程序是本地过程,不需要内核调用。不需要陷阱,上下文切换,也不需要对Cache进行刷新。
允许每个进程有自己定制的调度算法。
扩展性:内核空间中内核线程需要一些固定表格空间和堆栈空间,如果数量过大,就会出现问题。
缺点:
阻塞系统调用:假设在没有任何击键之前,一个线程读取键盘,让该线程实际进行该系统调用是不可接受的。因为这会停止所有线程。使用线程的一个目标是,首先要允许每个线程使用阻塞调用,但是还要避免被阻塞的线程影响其他线程。有了阻塞系统调用,这个目标很难实现。
改进:如果某个调