一、线程的3种实现方式
1.用户级线程
(1)线程的用户级线程实现方式
有关线程管理的所有工作都由应用程序完成,内核意识不到多线程的存在。用户级线程仅存在于用户空间中,此类线程的创建、撤销、线程之间的同步与通信功能,都无法利用系统调用来实现。应用程序需要通过使用线程库来控制线程。 通常,应用程序从单线程起始,在该线程中开始运行,在其运行的任何时刻,可以通过调用线程库中的派生创建一个在相同进程中运行的新线程。由于线程在进程内切换的规则远比进程调度和切换的规则简单,不需要进行用户态/核心态切换,所以切换速度快。
因为用户级线程驻留在用户空间,且管理和控制它们的线程也在用户空间,每个线程并不具有自身的线程上下文,所以它们对于操作系统是不可见的,这也就是它无法被调度到处理器内核的原因。
(2)优缺点:
1、内核实现简单,但是用户程序实现复杂,线程的创建、调度、管理都需要用户程序自己完成。
2、如果进程中的一条线程阻塞,则这个进程会被阻塞。
3、切换效率高, 不需要陷入内核
4.线程发生I/O或页面故障引起的阻塞时,如果调用阻塞系统调用则内核由于不知道有多线程的存在,而会阻塞整个进程从而阻塞所有线程, 因此同一进程中只能同时有一个线程在运行(在用户级线程中,每个进程里的线程表在运行时由系统管理。当一个线程转换到就绪状态或阻塞状态时,在该线程表中存放重新启动该线程所需的信息,与内核在进程表中存放的进程的信息完全一样)。
5.页面失效也会产生类似的问题。
6.一个单独的进程内部,没有时钟中断,所以不可能用轮转调度的方式调度线程。
7.资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用,因此对于多线程并不能被多核系统加速。
2.内核级线程
(1)实现方式
内核线程建立和销毁都是在内核的支持下运行,由操作系统负责管理,通过系统调用完成的。
线程管理的所有工作由内核完成,应用程序没有进行线程管理的代码,只有一个到内核级线程的编程接口。内核为进程及其内部的每个线程维护上下文信息,调度也是在内核基于线程架构的基础上完成。
内核线程驻留在内核空间,它们是内核对象。操作系统调度器管理、调度并分派这些线程。运行时库为每个用户级线程请求一个内核级线程,将用户进程映射或绑定到上面。用户线程在其生命期内都会绑定到该内核线程。一旦用户线程终止,两个线程都将离开系统。这被称作”一对一”线程映射。
内核空间内为每一个内核支持线程设置了一个线程控制块(TCB),内核根据该控制块,感知线程的存在,并进行控制。
操作系统的内存管理和调度子系统必须要考虑到数量巨大的用户级线程。您必须了解每个进程允许的线程的最大数目是多少。操作系统为每个线程创建上下文。进程的每个线程在资源可用时都可以被指派到处理器内核,这些线程可以在全系统内进行资源的竞争。
(2)内核线程的特点
内核线程建立和销毁都是在内核的支持下运行,由操作系统负责管理,通过系统调用完成的。效率较低;切换时与用户级线程比较,切换效率低,每次切换都需要从用户态切换到内核态。当某个线程希望创建一个新线程或撤销一个已有线程时,它进行一个系统调用。
(3)优点
多处理器系统中,内核能够并行执行同一进程内的多个线程。
如果进程中的一个线程被阻塞,能够切换同一进程内的其他线程继续执行(用户级线程的一个缺点)。
所有能够阻塞线程的调用都以系统调用的形式实现,代价较大。
当一个线程阻塞时,内核根据选择可以运行另一个进程的线程。
信号是发给进程而不是线程的,当一个信号到达时,应该由哪一个线程处理它?线程可以“订阅”它们感兴趣的信号(订阅发布模型)。
3.组合线程
在一些系统中,使用组合方式的多线程实现, 线程创建完全在用户空间中完成,线程的调度和同步也在应用程序中进行。一个应用程序中的多个用户级线程被映射到一些(小于或等于用户级线程的数目)内核级线程上。
参考:https://blog.csdn.net/u013007900/article/details/79620082