在我们目前的现代操作系统大多数支持多线程的概念,每个进程中至少有一个线程,所以即使没有使用多线程编程技术,进程也含有一个主线程。也就是说,CPU中执行的是线程,线程是程序的最小执行单位,是操作系统分配CPU时间的最小实体。
一个线程的执行是由主线程开始的,如果需要可以在程序的任何地方开辟新的线程,其他线程都是由主线程创建。
线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。
线程可与属于同一进程的其他线程共享进程所拥有的全部资源,但是其本身基本不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器,一组寄存器和线程栈,线程栈用于维护线程在执行代码时所需要的所有函数参数和局部变量)。
注:一个进程中的所有线程共享它们父进程的变量,但同时每个线程可以拥有自己的变量
一个线程从创建到结束,是一整个生命周期,它总是处于下面4个状态中的一个:
线程能够运行的条件已经满足,只是在等待处理器的调度(处理器要根据调度策略来把就绪态的线程调度到处理器中运行)
运行态表示线程正在处理器中运行,正占用着处理器
由于在等待处理群之外的其他条件而无法运行的状态叫作阻塞态。这里的其他条件包括I/O操作,互斥锁的释放,条件变量的改变等
终止态就是线程的线程函数运行结束或被其他线程取消后处于的状态。线程处于终止态后应该及时进行资源回收
句柄是用来标识线程对象的,而线程本身用ID来标识。在创建线程的时候,系统会为线程分配一个唯一的ID作为线程的标识,这个ID从线程创建开始存在,一直伴随着线程的结束才消失。通常线程创建成功后会返回一个线程ID。
在Linux C/C++开发环境中,通常有两种方式来开发多线程程序,一种是利用POSIX多线程API函数来开发多线程程序,另外一种是利用C++自带线程类来开发多线程程序。
常见的与线程有关的基本API函数
| API函数 | 含 义 |
|---|---|
| pthread_create | 创建线程 |
| pthread_exit | 线程终止自身执行 |
| pthread_join | 等待一个线程的结束 |
| pthread_self | 获取线程ID |
| pthread_cancel | 取消另一个线程 |
| pthread_exit | 在线程函数中调用来退出线程函数 |
| pthread_kill | 向线程发送一个信号 |
注:使用这些API函数,需要包含头文件pthread.h,并且在编译的时候需要加上库pthread,表示包含多线程库文件
C++11新标准中引入了5个头文件来支持多线程编程,分别是atomic, thread, mutex, condition_variable和future
类std::thread的常用成员函数
| 成员函数 | 说明(public 访问方式) |
|---|---|
| thread | 构造函数,有4种构造函数 |
| get_id | 获得线程ID |
| joinable | 判断线程对象是否可连接的 |
| join | 等待线程结束,该函数是阻塞函数 |
| native_handle | 用于获得与操作系统相关的原生线程句柄(需要本地库支持) |
| swap | 线程交换 |
| detach | 分离线程 |