一、线程池thread
std::thread 在#include < thread > 头文件中声明。
进程:就是运行中的程序
线程:就是进程中的进程
1.1、语法
1.1.1、构造函数
- 默认构造函数
std::thread() noexcept;
- 初始化构造函数
初始化构造函数创建一个新的线程,并将该线程与一个可调用对象(如函数、Lambda 表达式、函数对象等)关联。f:可调用对象(函数、Lambda 表达式、函数对象等)。args:传递给可调用对象的参数。
template <class Function, class... Args>
explicit thread(Function&& f, Args&&... args);
- 拷贝构造函数
//拷贝构造函数(被禁用),意味着不可被拷贝构造
thread(const thread&)=delete;
//所以不能写成
thread t1;
thread t2 = t1;//错误
- move构造函数
//move构造函数,调用成功之后x不代表任何thread执行对象
注意:可被jionable的thread对象必须在他们销毁之前被主线程join或者将其设置为detached。
thread(thread&& x)noexcept;
thread t1;
thread t2 = move(t1);//正确
1.1.2主要成员函数
join()
join:等待线程执行完毕后返回。
首先看下面例子:
void printHelloWorld()
{
cout<<"Hello World"<<endl;
}
int main()
{
thread thread1(printHelloWorld);
//如果不使用thread1.join();
//程序是按单线程,从上到下走的,
//当走到thread时,thread里面肯定需要运行,
//但是主程序不在意他,继续向下走,就导致
//报错。因为主程序走完了,但是thread1可能没有走完。
thread1.join();
return 0;
}
joinable()
joinable:判断线程是否可以加入等待。
getid()
getid:获取线程ID,返回类型std::thread::id对象
detach()
detach:detach调用之后,目标线程就成为了守护线程,驻留后台运行,与之相关的std::thread对象失去目标线程的关联,无法再通过std::thread对象取得该线程的控制权(例如join)。当线程执行完之后,线程就结束了,运行时库负责清理与该线程的资源。它可能带来崩溃,谨慎使用。
detach()是 C++ 标准库中std::thread类的一个成员函数,用于将线程与其创建的std::thread对象分离。分离后的线程会独立运行,不再与std::thread对象关联。分离后的线程也称为守护线程
- 调用detach之后:
- *this不再代表任何线程执行实例。
- joinable==false
- get_id()==std::thread::id()
1.1.2、简单线程的创建
- 传入0个值
- 传入2个值
- 传入引用(std::ref())
- 传入类函数
- detach
- move
void printHelloWorld()
{
cout<<"Hello World"<<endl;
}
int main()
{
//1.
thread thread1(printHelloWorld);
thread1.join();
return 0;
}
void func2(int a,int b){
cout<<a+b<<endl;
}
int main()
{
//2.
int a = 10;
int b =20;
thread thread2(func2,a,b);
thread2.join();
return 0;
}
void func3(int &c){
c+=10;
}
int main()
{
//3.
int c =10;
thread thread3(func3,std::ref(c));
thread3.join();
cout<<c<<endl;//20
return 0;
}
class A{
public:
//4.类函数
void func4(int a){
cout<<"thread:"<<name_<<",fun4 a= "<<a<<endl;
}
void setName(string name){
name_ = name;
}
void displayName(){
cout<<"this:"<<this<<endl;
}
void play(){
cout<<"play call!"<<endl;
}
private:
string name_;
};
int main()
{
//4.
A* a4_ptr = new A();
a4_ptr->setName("darren");
thread thread4(&A::func4,a4_ptr,100);
thread4.join();
delete a4_ptr;
return 0;
}
//5.detach
void func5(){
this_thread::sleep_for(std::chrono::seconds(1));
cout<<"func5 leave"<<endl;
}
int main()
{
//5.
thread thread5(&func5);
thread5.detach();//脱离
return 0;
}
//6.move
void func6(){
this_thread::sleep_for(std::chrono::seconds(1));
cout<<"func5 leave"<<endl;
}
int main()
{
//6.
int x = 10;
thread thread6(&func6);
thread thread7(std::move(thread6));//thread6将线程失去所有权
thread6.join();//掏出异常
thread7.join();
return 0;
}
1.1.3、线程封装
封装线程,子类可以继承,然后子类能实现具体的业务处理逻辑。
1.1.4、this_thread::
this_thread 是 C++ 标准库中的一个命名空间,提供了一些与当前线程相关的工具函数。它定义在 <thread> 头文件中,主要用于操作当前线程的行为,例如让当前线程休眠、获取线程 ID 等。
1. this_thread::get_id()
- 获取当前线程的唯一标识符(
std::thread::id类型)。 - 每个线程都有一个唯一的 ID,可以用来区分不同的线程。
#include <iostream>
#include <thread>
using namespace std;
void printThreadId() {
cout << "Current thread ID: " << this_thread::get_id() << endl;
}
int main() {
thread t(printThreadId);
cout << "Main thread ID: " << this_thread::get_id() << endl;
t.join();
return 0;
}
2. this_thread::sleep_for()
- 让当前线程休眠一段指定的时间。
- 参数是一个时间间隔,通常使用
std::chrono::duration表示.
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main() {
cout << "Sleeping for 2 seconds..." << endl;
this_thread::sleep_for(chrono::seconds(2)); // 休眠 2 秒
cout << "Awake!" << endl;
return 0;
}
3. this_thread::sleep_until()
- 让当前线程休眠直到某个时间点。
- 参数是一个时间点,通常使用
std::chrono::time_point表示。
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main() {
auto wakeupTime = chrono::steady_clock::now() + chrono::seconds(3); // 3 秒后
cout << "Sleeping until 3 seconds later..." << endl;
this_thread::sleep_until(wakeupTime); // 休眠到指定时间点
cout << "Awake!" << endl;
return 0;
}
4. this_thread::yield()
- 让当前线程主动放弃 CPU 时间片,让其他线程有机会运行。
- 通常用于忙等待(busy-wait)场景,避免浪费 CPU 资源。
#include <iostream>
#include <thread>
#include <atomic>
using namespace std;
atomic<bool> ready(false);
void waitForReady() {
while (!ready) {
this_thread::yield(); // 让出 CPU 时间片
}
cout << "Ready!" << endl;
}
int main() {
thread t(waitForReady);
this_thread::sleep_for(chrono::seconds(1)); // 模拟准备工作
ready = true;
t.join();
return 0;
}