一、多线程概述
进程是系统中程序执行和资源分配的基本单位。每个进程有自己的数据段、代码段和堆栈段,这就造成进程在进行切换等操作时都需要有比较复杂的上下文切换等动作。为了进一步减少处理器的空转时间支持多处理器和减少上下文切换开销,于是就出现了线程。
线程通常叫作轻量级进程,线程是在共享内存空间中并发执行的多道执行路径,是一个更加接近于执行体的概念,拥有独立的执行序列,是进程的基本调度单元,每个进程至少有一个 main 线程。它与同进程中其他线程共享进程空间 {堆 代码 数据 文件描述符 信号等},只拥有自己的栈空间,大大减少了上下文切换的开销。
进程和线程的关系如下所示:
线程和进程在使用上各有优缺点:线程执行开销小,占用的 CPU 资源少,线程之间的切换快,但不利于资源的管理和保护;反而进程正相反。从可移植性来说,多进程的可移植性要好些。
同进程一样,线程也将相关的变量值放在线程控制表内。一个进程可以有多个线程,也就是有多个线程控制表及堆栈寄存器,但却共享一个用户地址空间。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响。
二、线程分类
线程按调度者不同可分为用户级线程和核心级线程。
用户级线程:主要解决上下文切换问题,调度算法和调度过程全部由用户决定,在运行时不需要特定的内核支持。缺点是无法发挥多处理器的优势。
核心级线程:允许不同进程中的线程按照同一相对优先调度方法调度,发挥多处理器的并发优势。
现在大多数系统都采用用户级线程和核心级线程并存的方法。一个用户级线程可以对应一个或多个核心级线程,也就是“一对一”或“一对多”模型。
三、线程创建的Linux实现
Linux 的线程是通过用户级的函数库实现的,一般采用 pthread 线程库实现线程的访问和控制,它用第 3 方 posix 标准的 pthread,具有良好的可移植性。编译的时候要在后面加上 -lpthread 。
创建 退出 等待
多进程 fork() exit() wait()
多线程 pthread_create() pthread_exit() pthread_join()