C++11 std::thread 学习笔记
2019-03-29 本文已影响0人
lixin_karl
主要方法介绍
template<typename _Callable, typename... _Args>
explicit thread(_Callable&& __f, _Args&&... __args) 线程创建函数(函数,参数...)
void swap(thread& __t) noexcept 交换线程
bool joinable() const noexcept 判断线程是否可以加入等待
void join() 加入等待,等待这个线程结束。
void detach() 分离线程 设置线程为独立线程。
native_handle_type native_handle() 获得线程句柄
static unsigned int hardware_concurrency() noexcept 返回系统cpu核数
例子
void Run1(int a)
{
std::cout<<"Run1("<<a<<")"<<std::endl;
}
void Run2(int a,int b)
{
std::cout<<"Run2("<<a<<","<<b<<")"<<std::endl;
}
int main()
{
auto t1 = std::thread(Run1,3);
auto t2 = std::thread(Run2,5,7);
t1.join();t2.join();
}
输出结果
Run1(3)
Run2(5,7)
join函数是要求等待线程结束后,主线程才能结束,如果调用join函数的话会出现
terminate called whithout an active exception
错误,Google给出的解答是,这由于在停止线程时,导致它脱离了栈的控制,这就意味着你必须使用join 函数 或者 detach函数。
detach例子
void Run1(int a)
{
std::cout<<"Run1("<<a<<")"<<std::endl;
}
void Run2(int a,int b)
{
std::cout<<"Run2("<<a<<","<<b<<")"<<std::endl;
}
int main()
{
auto t1 = std::thread(Run1,3);
auto t2 = std::thread(Run2,5,7);
t1.detach();t2.detach();
}
输出结果
Run1(3)
detach函数会导致t1 t2 从主线程分离开来,主线程结束的时候 t2 还未来得及打印数据,导致只出现一条打印数据。
原子变量与线程安全
普通变量
int sum = 0;
int N = 1000000;
void Count()
{
for(auto i = 0; i <N ; ++i)
{
++sum;
}
}
int main()
{
auto start = clock();
auto t1 = std::thread(Count);
auto t2 = std::thread(Count);
t1.join();
t2.join();
auto end = clock();
std::cout<<"Sum = "<<sum<<"消耗时间:"<<end-start<<std::endl;
}
加锁
int sum = 0;
int N = 1000000;
std::mutex m;
void Count()
{
for(auto i = 0; i <N ; ++i)
{
m.lock();
++sum;
m.unlock();
}
}
int main()
{
auto start = clock();
auto t1 = std::thread(Count);
auto t2 = std::thread(Count);
t1.join();
t2.join();
auto end = clock();
std::cout<<"Sum = "<<sum<<"消耗时间:"<<end-start<<std::endl;
}
输出结果
Sum = 2000000消耗时间:94
原子变量
int sum = 0;
int N = 1000000;
std::mutex m;
std::atomic_int atomic_sum = 0;
void Count()
{
for(auto i = 0; i <N ; ++i)
{
++atomic_sum;
}
}
int main()
{
auto start = clock();
auto t1 = std::thread(Count);
auto t2 = std::thread(Count);
t1.join();
t2.join();
auto end = clock();
std::cout<<"Sum = "<<atomic_sum<<"消耗时间:"<<end-start<<std::endl;
}
输出结果
Sum = 2000000消耗时间:46
普通变量导致算出的最终结果不是我们所期望的,导致错误;对普通变量加锁后,得到了期望结果;使用原子变量后,效率得到了提升,而且结果正确。
类中使用线程
class Task{
public:
void Start()
{
thread = std::thread([&]{
this->Run();
});
}
void Join()
{
thread.join();
}
virtual void Run() = 0;
private:
std::thread thread;
};
class Task1 : public Task{
void Run() override
{
std::cout<<"I am Job 1"<<std::endl;
}
};
class Task2 : public Task{
void Run() override
{
std::cout<<"I am Job 2"<<std::endl;
}
};
int main()
{
Task1 t1;
Task2 t2;
t1.Start();
t2.Start();
t1.Join();
t2.Join();
return 0;
}
输出结果
I am Job 1
I am Job 2
使用组合的方式可以很方便的做多线程业务逻辑。