1、为什么使用线程
由于进程之间的通信和共享数据操作复杂同时维护进程的系统开销较大,加上创建进程需要分配资源,建立PCB,撤销进程时需要回收资源,撤销PCB,进程切换时需要保存当前进程的状态信息等系列操作,促使提出一种新的实体,可以满足以下特性:
(1) 实体之间可以并发地执行;
(2) 实体之间共享想同的地址空间。 这种实体就是线程(Thread),线程可以并发地去执行同时线程之前可以共享想同的地址空间。
2、线程的定义
线程就是进程当中的一条执行流程。 引入线程之后,需要从两个方面来重新理解进程:
从资源组合的角度:进程把一组相关的资源组合起来,构成了一个资源平台(环境),包括地址空间(代码段,数据段)、打开的文件等各种资源。
从运行的角度:代码在这个资源平台上的一条执行流程(线程)。
线程有自己的线程控制块称为TCB(Thread Control Block),每一个线程自己的TCB 控制自己线程的程序计数器(PC),堆栈资源(SP)、状态资源(state)和寄存器(Registers)。处于一个进程之中的不同线程可以共享进程的资源有动态链接库资源(DLL),堆资源(Heap),数据资源(initialized data)和代码资源(code)。
从另一个角度看,线程=进程-共享资源,线程同步和共享进程资源的特性促成了其有以下优点:一个进程中可以同时存在多个线程;各个线程之间可以并发地执行;各个线程之间可以共享地址空间和文件等资源。
从另一个方面看,一个线程的崩溃,会导致其所属进程的所有线程的崩溃,这也是线程的缺点,导致其安全可靠性较难以保证。
权衡线程和进程的标准:当需要进行高性能计算时,使用线程会比较适用;但是Internet浏览器,其安全性优先级更高,所以使用进程开发更加适用,因为某个网页崩溃不会影响到其他网页的正常浏览和运行。
线程独占的资源和共享资源示意图如下图所示:
2.1 进程和线程的比较
·进程是资源资源分配的单位,进程是CPU调度的单位;
进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈等;
·线程同样具有就绪、阻塞和执行三种基本状态,同样具有状态之间的转换关系;
·线程能减少并发执行的时间和空间开销:
·线程的创建时间比进程短;
·线程的终止时间比进程短;
·同一个进程内的线程切换时间比进程短;
·由于同一个进程的各个线程之间共享内存和文件资源,
可以直接进行不通过内核的通信。
2.2 线程的实现
用户线程: 在用户空间实现,如POSIX Pthread,Mach C-thread,Solaris threads;内核线程: 在内核中实现,如Windows,Solaris,Linux;轻量级进程:在内核中实现,支持用户线程,Solaris,lightWeight Process。用户线程和内核线程的对应关系有以下几种:多对一(多个用户线程对应一个内核线程);一对一(一个用户线程对应一个内核线程)和和多对多(多个用户线程对应多个内核线程)。
2.2.1 用户线程
在用户空间实现的线程机制,他不依赖与操作系统的内核,由一组用户及的线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。用户线程示意图如上图所示。
由于用户线程的维护有相应的进程来完成(通过线程库函数),不需要操作系统内核了解用户线程的存在,可以用于不支持线程技术的多进程操作系统;每个进程都需要自己私有的线程控制块(TCB)列表,用来跟踪记录他的各个线程的状态信息(PC,栈指针,寄存器),TCB由线程库函数来维护;用户线程的切换也是由线程库函数来完成,无需用户态/核心态的转换,所以速度特别快;允许每个进程拥有自定义的线程调度算法。
用户线程有以下缺点: 阻塞性的系统调用如何实现?因为如果一个进程中的某个用户线程发起系统调用而阻塞,则整个进程都将等待;当一个线程开始运行后,除非他主动地交出CPU的使用权,否则它所在的进程当中的其他线程将无法运行;由于时间片分配给进程,所以与其他进程比,在多线程执行时,每个线程得到的时间片较少,执行会较慢。
2.2.2 内核线程
内核线程是指在操作系统的内核当中实现的一种线程机制,有操作系统的内核来完成线程的创建、终止和管理。在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息(PCB和TCB);线程的创建、终止和切换都是通过系统调用/内核函数的方式来进行,由内核完成,因此系统开销较大;在一个进程当中,如果某个内核线程发起系统调用而被阻塞,并不会影响其他内核线程的执行;时间片直接分配给线程,多线程的进程可以获得更多的CPU时间;Windows NT和Windows 2000/XP支持内核线程。内核线程示意图如下图所示。
2.2.3 轻量级进程-Lightweight Process LWP
它是内核支持的用户线程。一个进程可以有一个或者多个轻量级进程,每个轻量级进程由一个单独的内核线程来支持。(Solaris/Linux)轻量级进程示意图如下图所示。