系列文章目录
C++11多线程---线程(一)
C++11多线程---原子操作变量(四)
C++11多线程---异步操作(五)
前言
C++11 引入了 thread 类,降低了使用多线程的复杂度,原先使用多线程只能用系统的 API,无法解决跨平台问题,代码平台的改变,对应多线程代码也必须要修改。在 C++11 中只需使用语言层面的 thread 可以解决这个问题。编写并发程序需引入头文件<thread>。
一、线程thread
1、语法
1.1 构造函数
默认构造函数
//创建一个空的 thread 执行对象。
thread() _NOEXCEPT
{ // construct with no thread
_Thr_set_null(_Thr);
}
初始化构造函数
//创建std::thread执行对象,该thread对象可被joinable,新产生的线程会调用threadFun函数,该函数的参数由 args 给出
template<class Fn, class... Args>
explicit thread(Fn&& fn, Args&&... args);
拷贝构造函数
// 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
thread(const thread&) = delete;
Move构造函数
//move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为
detached。
thread(thread&& x)noexcept
// 构造函数的使用
#include <iostream>
#include <thread>
using namespace std;
void threadFun(int &num) // 引用传递
{
cout << "this is thread fun !" <<endl;
cout <<" num = "<<num<<endl;
}
int main()
{
int num = 10;
thread t1(threadFun, std::ref(num)); // 引用传递
thread t2(std::move(t1)); // t1 线程失去所有权
thread t3;
t3 = std::move(t2); // t2 线程失去所有权
// t1.join(); // 会出错,因为t1已被move
t3.join();
cout<<"last num is "<<num<<endl;
return 0;
}
1.2 主要成员函数
2 简单线程的创建
使用std::thread创建线程,提供线程函数或者函数对象,并可以同时指定线程函数的参数。
#include <iostream>
#include <thread>
using namespace std;
void func1()
{
cout << "func1" << endl;
}
void func2(int a, int b)
{
cout << "func2 a + b = " << a+b << endl;
}
void func3(int &c) // 引用传递
{
cout << "func3 c = " << &c << endl;
c += 1;
}
class A
{
public:
// 4. 传入类函数
void func4(int a)
{
// std::this_thread::sleep_for(std::chrono::seconds(1));
cout << "thread:" << name_<< ", fun4 a = " << a << endl;
}
void setName(string name) {
name_ = name;
}
void displayName() {
cout << "this:" << this << ", name:" << name_ << endl;
}
void play()
{
std::cout<<"play call!"<<std::endl;
}
private:
string name_;
};
//5. detach
void func5()
{
cout << "func5" << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
cout << "func5 leave " << endl;
}
// 6. move
void func6()
{
cout << "func6" <<endl;
}
int main()
{
// 1. 传入0个值
cout << "\n\n main1--------------------------\n";
std::thread t1(&func1); // 只传递函数
t1.join(); // 阻塞等待线程函数执行结束
// 2. 传入2个值
cout << "\n\n main2--------------------------\n";
int a =10;
int b =20;
std::thread t2(func2, a, b); // 加上参数传递,可以任意参数
t2.join();
// 3. 传入引用
cout << "\n\n main3--------------------------\n";
int c =10;
std::thread t3(func3, std::ref(c)); // 加上参数传递,可以任意参数
t3.join();
cout << "main3 c = " << &c << ", "<<c << endl;
// 4. 传入类函数
cout << "\n\n main4--------------------------\n";
A * a4_ptr = new A();
a4_ptr->setName("darren");
std::thread t4(A::func4, a4_ptr, 10);
t4.join();
delete a4_ptr;
// 5.detach
cout << "\n\n main5--------------------------\n";
std::thread t5(&func5); // 只传递函数
t5.detach(); // 脱离
// std::this_thread::sleep_for(std::chrono::seconds(2)); // 如果这里不休眠会怎么样
cout << "\n main5 end\n";
// 6.move
cout << "\n\n main6--------------------------\n";
int x = 10;
thread t6_1(func6);
thread t6_2(std::move(t6_1)); // t6_1 线程失去所有权
t6_1.join(); // 抛出异常
t6_2.join();
return 0;
}
3、补充
this_thread - C++ Reference (cplusplus.com)
- get_id :Get thread id (function )
- yield :Yield to other threads (function ),比如范例:yield - C++ Reference (cplusplus.com)
- sleep_until :Sleep until time point (function )
- sleep_for :Sleep for time span (function )
总结
本文仅仅简单介绍了c++11线程的基本使用以及相关的API调用。