线程的引入
线程的引入
为什么引入线程???
引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务。并且引入线程之后,进程只作为除CPU之外的系统资源的分配单元(像打印机、内存地址空间等都是分配给进程的)。下面第一张图对此做了说明,进程还是拥有资源,而线程继承了CPU调度的工作。
引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务。并且引入线程之后,进程只作为除CPU之外的系统资源的分配单元(像打印机、内存地址空间等都是分配给进程的)。下面第一张图对此做了说明,进程还是拥有资源,而线程继承了CPU调度的工作。
开销的考虑
进程相关的操作:创建进程、撤销进程、进程通信、进程切换 -> 时间/空间开销大、限制了并发度的提高
而线程:创建一个新线程花费时间少(撤销也是);两个线程切换花费时间少;线程之间相互通信无须调用内核(并且同一进程内的线程共享内存和文件)
线程的基本概念
线程:
线程和进程相似,但线程是一个比进程更小的执行单位,一个进程在其执行的过程中可以产生多个线程。与进程不同的是同一进程的不同线程间共享进程的堆和方法区资源。所以系统在产生一个线程或是在各个线程之间做切换工作时,负担要比进程小得多。但每个线程有自己的程序计数器,虚拟机栈和本地方法栈。线程是进程中的一个运行实体,是CPU的调度单位,有时候将线程称为一个轻量级进程。在同一进程中增加了多个执行序列(线程)。
线程的属性
线程机制的实现
分为用户级线程、核心级线程(当然还有混合模型线程,但是好像用的不多了,这边就不说明了)
一、用户级线程(USER LEVEL THREAD)
顾名思义,在用户空间建立线程库:提供一组管理线程的过程。是由一个叫运行时系统(Run-time-system)来完成线程的管理工作(操作、线程表)。但是内核管理的还是进程,不知道线程的存在,因为用户级线程是在用户层面去执行的。所以线程之间的切换不需要内核给特权。
例子:POSIX线程库 -- PTHREAD 多线程编程接口,以线程库方式提供给用户
注意一下Pthread_yield() 该线程是自愿让出CPU给其他线程的,因为内核根本不知道线程的存在,如果不主动让出处理器资源,其他线程就无法被调度。
用户级线程优点:线程切换快;调度算法是应用程序特定的;用户级线程可运行在任何操作系统上(只要系统能上能加载线程库)。
用户级线程缺点:内核只将处理器分配给进程,同一进程中的两个线程不能同时运行于两个处理器上;大多数系统调用是阻塞的,因此,由于内核阻塞进程,故进程中所有线程也被阻塞。
二、核心级线程(KERNEL LEVEL THREAD)
和用户级线程不同的是,核心级线程由 内核管理所有线程,并向应用程序提供API;内核维护同时维护进程和线程的上下文;线程的切换需要内核支持了;以线程为基础进行调度。
典型例子:Windows