原文:
C++11 threads, locks and condition variables
C++11 线程,锁和条件变量This article is a walk-through the C++11 support for threads and synchronization mechanisms (mutexes and condition variables).
这篇文章主要是介绍C++11对线程和同步机制(互斥锁和条件变量)的支持。1.线程(Threads)
C++11类库中引入了std::thread类,目的是在语言层面对线程操作提供支持。std::thread可以在函数,lambda表达式中使用,另外它还允许你为线程函数传递任何参数。#include <thread>
void func(){ // do some work} int main(){ std::thread t(func); t.join(); return 0;}在这个例子里 t 是thread对象,func()表示在线程环境下运行的函数。join()方法的调用,可以理解为,主线程main()阻塞在join()处,直到线程函数退出才继续运行。当然,func函数可以传递任何你需要的参数。
void func(int i, double d, const std::string& s)
{ std::cout << i << ", " << d << ", " << s << std::endl;} int main(){ std::thread t(func, 1, 12.50, "sample"); t.join(); return 0;}上面可以看到,我们可以以值传递的方式来传递任何参数,但是,如果我们想要传引用的话,需要是用std::ref或std::cref,参考下面的例子。
void func(int& a)
{ a++;} int main(){ int a = 42; std::thread t(func, std::ref(a)); t.join(); std::cout << a << std::endl; return 0;}程序输出43,如果没有使用std::ref的话则打印42。
处理join方法外,thread还提供另外两个操作
1)swap 交换两个线程句柄(好像在实际项目中没啥卵用,有实际应该过的朋友可以来补充)2)detach 允许线程脱离线程对象独立运行,detach后的线程是无法join(wait)到他的返回的;int main()
{ std::thread t(funct); t.detach(); return 0;} 另外值得提一下的是关于线程异常的问题,如果线程函数抛出异常,是不能被捕获的。try
{ std::thread t1(func); std::thread t2(func); t1.join(); t2.join();}catch(const std::exception& ex){ std::cout << ex.what() << std::endl;}但当线程产生异常时,我们可以在线程中捕获它,将其暂时存放,而在稍后的时候对异常进行处理。
std::mutex g_mutex;
std::vector<std::exception_ptr> g_exceptions;void throw_function()
{ throw std::exception("something wrong happened");}void func()
{ try { throw_function(); } catch(...) { std::lock_guard<std::mutex> lock(g_mutex); g_exceptions.push_back(std::current_exception()); }}int main()
{ g_exceptions.clear();std::thread t(func);
t.join();for(auto& e : g_exceptions)
{ try { if(e != nullptr) { std::rethrow_exception(e); } } catch(const std::exception& e) { std::cout << e.what() << std::endl; } }return 0;
}2.锁(Lock)
在上面的例子中我们需要同步控制变量g_exceptions的访问,以确保同事只用一个线程修改(push)这个变量。
C++11中提供了4中同步控制的方法:1)