1.thread参数使用类
绑定类方法,直接使用std::thread(&CThread::run,&thread);
例子:
CThread thread;
std::thread th = std::thread(&CThread::run,&thread);
测试:
#include <iostream>
#include <thread>
using namespace std;
class CThread
{
public:
CThread()
{
cout<<__FUNCTION__<<endl;
}
~CThread()
{
cout<<__FUNCTION__<<endl;
}
void run(int n)
{
cout<<__FUNCTION__<<n<<endl;
}
};
int main()
{
CThread thread;
std::thread th = std::thread(&CThread::run,&thread,10086);
th.join();
return 0;
}
输出结果:一次构造和析构,一次run调用
CThread
run10086
~CThread
注意 线程应该要指明join或者detach,否则程序会异常终止
测试
int main()
{
CThread thread;
std::thread th = std::thread(&CThread::run,&thread,10086);
// th.join();
return 0;
}
结果
CThread
run10086
terminate called without an active exception
解决办法
可以参考RAII封装,如下面第六条
2.使用普通方法
void fun_thread(int m)
{
cout<<__FUNCTION__<<" "<<m<<endl;
}
int main()
{
std::thread(fun_thread,100).join();
return 0;
}
3. thread使用Lambda表达式
int main()
{
std::thread([]{ cout<<"Lambda"<<endl;}).join();
return 0;
}
4. 可以使用仿函数
class CThread
{
public:
CThread()
{
cout<<__FUNCTION__<<" "<<this<<" "<<endl;
}
CThread(const CThread&)
{
cout<<__FUNCTION__<<" copy "<<this<<" "<<std::this_thread::get_id()<<endl;
}
~CThread()
{
cout<<__FUNCTION__<<this<<" "<<std::this_thread::get_id()<<endl;
}
//仿函数
void operator()() const
{
cout<<__FUNCTION__<<this<<" "<<std::this_thread::get_id()<<endl;
}
};
int main()
{
CThread thread;
std::thread{thread}.join();
return 0;
}
输出,有三次析构,即创建和到子线程都有拷贝
CThread 0x64febb
CThread copy 0x64fe8b 1
CThread copy 0xe618ac 1
~CThread0x64fe8b 1
operator()0xe618ac 2
~CThread0xe618ac 2
~CThread0x64febb 1
5. 作为参数
可以作为参数传递
void threadCall(std::thread th)
{
if(th.joinable()){
th.join();
}
}
int main()
{
std::thread th =std::thread([]{ cout<<"Lambda"<<endl;});
threadCall(std::move(th));
return 0;
}
注意std::thread只能使用std::move,move前要确认是否当前可以赋值
int main()
{
std::thread th =std::thread([]{ cout<<"Lambda1"<<endl;});
std::thread th1 = std::move(th);
th = std::thread([]{ cout<<"Lambda2"<<endl;});
//th = std::move(th1); //th已经再次创建(Lambda2),不能再赋值其他,会异常终止,即move后原先无法管理
th1.join();
th.join();
return 0;
}
作为返回值
void createfun()
{
cout<<__FUNCTION__<<" "<<endl;
}
std::thread createThread()
{
return std::thread(createfun);
}
int main()
{
createThread().join();
return 0;
}
6.结合std::move未join异常处理
在一些临时创建线程,有时线程退出没有处理会程序退出,可以封装个类处理
class ScopedThread
{
public:
explicit ScopedThread(std::thread t):m_thread{std::move(t)}
{
if(!m_thread.joinable()){
throw std::logic_error("No thread");
}
}
~ScopedThread()
{
m_thread.join();
}
ScopedThread(const ScopedThread& )=delete;
ScopedThread& operator=(const ScopedThread& )=delete;
private:
std::thread m_thread;
};
int main()
{
std::thread th{[]{std::this_thread::sleep_for(std::chrono::seconds(10));cout<<__FUNCTION__<<" "<<std::this_thread::get_id()<<endl;}};
ScopedThread sth{std::move(th)};
return 0;
}
查看可以运行线程数
std::thread::hardware_concurrency()
查看程序id
std::this_thread::get_id()
id可以比较
if(std::this_thread::get_id()==workid){...}