目录
一、thread类的简单介绍
在C++11中,实际上既可以说存在“线程类”,也可以说引入了“线程库”的支持。更准确地说,C++11标准库通过<thread>头文件提供了一系列与线程相关的类和函数,这些共同构成了C++11的线程库。
C++11标准库通过<thread>头文件提供了一系列与线程相关的类和函数,这些共同构成了C++11的线程库。C++11对线程进行支持,使得C++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。要使用标准库中的线程,必须包含< thread >头文件。
二、thread类的使用
2.1 关键成员函数及其功能
构造函数
thread() 构造一个线程对象,没有关联任何线程函数,不启动任何线程。
thread(fn,args1, args2,...) 构造一个线程对象,并启动一个新线程来执行函数fn,(args1,args2,...)为线程函数的参数。线程函数可以是可执行对象(函数指针、仿函数、lambda、包装器)。注:
- 不支持拷贝构造以及赋值,但支持移动构造和移动赋值。
- 带参构造,创建可执行线程。
- 先创建空线程对象,移动构造或者移动赋值,把右值线程对象转移过去。
线程id
thread::id 线程id,唯一标识一个线程。
id get_id() const noexcept; 返回当前线程的 thread::id 对象,用来唯一标识一个线程。noexcept 关键字用于指定函数不会抛出异常。
thread::id this_thread::get_id() noexcept; 线程对象调用的函数获取当前执行线程的 ID
阻塞当前线程
void jion(); 该函数调用后会阻塞住线程,当该线程结束后,主线程继续执行.
bool joinable() const noexcept; 检查thread对象是否代表一个可连接的线程,如果线程已经启动且尚未被 join() 或 detach() 调用,则该函数返回 true。如果线程是空的或已经被 join() 或 detach() 调用,则返回 false。
线程分离
void detach(); 在创建线程对象后马上调用,把被创建线程与线程对象分离开,分离的线程变为后台线程,创建的线程的"死活"就与主线程无关。
注意:
- 线程是操作系统中的一个概念,线程对象可以关联一个线程,用来控制线程以及获取线程的
状态。 - 当创建一个线程对象后,没有提供线程函数,该对象实际没有对应任何线程。
- thread类是防拷贝的,不允许拷贝构造以及赋值,但是可以移动构造和移动赋值,即将一个
线程对象关联线程的状态转移给其他线程对象,转移期间不影响线程的执行。 - 在线程对象销毁之前,必须要么调用 join() 要么调用 detach(),否则程序将终止线程并引发异常。
- 一旦线程被分离(detach),就不能再被连接(join),且线程对象不再与任何线程关联。
- 调用 join() 或 detach() 后,std::thread 对象不再表示任何线程,因此这些操作只能对每个线程对象执行一次。
- 可以通过jionable()函数判断线程是否是有效的,如果是以下任意情况,则线程无效
采用无参构造函数构造的线程对象;
线程对象的状态已经转移给其他线程对象;
线程已经调用jion或者detach结束;
简单举例:
#include <iostream>
#include <thread>
using namespace std;
void PrintThreadId()
{
thread::id id = this_thread::get_id();//线程对象调用的函数获取当前执行线程的 ID要使用this_thread::get_id(),而不是get_id()
cout << "Thread ID: " << id << endl;
}
void Func1()
{
//创建线程
thread t1(PrintThreadId);
//获取线程id
thread::id t1_id = t1.get_id();
cout << "Thread 1 ID: " << t1_id << endl;
// 判断线程是否可连接
if (t1.joinable())
t1.join();
else
cout << "Thread 1 is not joinable." << endl;
//创建另一个线程
thread t2(PrintThreadId);
//获取线程id
thread::id t2_id = t2.get_id();
cout << "Thread 2 ID: " << t2_id << endl;
// 判断线程是否可连接
if (t2.joinable())
t2.join();
else
cout << "Thread 2 is not joinable." << endl;
return;
}
int main()
{
Func1();
return 0;
}
有时输出结果可能混乱,这是由于线程间竞争条件和同步问题造成的,如多线程同时尝试写入同一个输出流。
2.2 并发和并行
并发(Concurrency)与并行(Parallelism)是两个经常被混淆的概念,但在计算机科学中它们有明确的定义和区别。
并发
并发指的是两个或多个事件在同一时间段内发生。在多线程或多进程编程中ÿ