原创 C++线程

2010-7-2 21:11 5405 6 6 分类: 工程师职场

挂上线程

新的C++0x线程库位于std::thread,它提供了建立并执行线程、等待线程完成、查询线程状态的机制。
你可以通过实例化一个带函数指针参数的std::thread来启动一个新线程:

  1. #include <thread>
  2.  
  3. void spellcheck();
  4. std::thread thr(spellcheck);

前面的代码在创建线程时调用spellcheck(),spellcheck()返回线程即完成。std::thread可以使用任何“可调用实体”(即实现了operator()()操作的对象)作为它的参数,而不仅仅是古老的函数指针。下面的代码用一个函数对象作为参数:

  1. class spellcheck
  2. {
  3.  void operator()();
  4. };
  5. spellcheck sp
  6. std::thread thr(sp);

thr实际上得到了一份sp的拷贝,如果你不想创建副本,使用reference wrapper来包装这个参数:

  1. spellcheck sp;
  2. std::thread thr(std::ref(sp));

现在看上去还不错,但是怎样传值给线程函数本身?在传统的线程框架中,典型的方式是包装所有的参数到一个不明确的指针中。幸运的是,那些日子已经一去不复返了。std::thread使用另一种叫做“可变参数模板”的新的C++功能,它允许你传送任意数量的参数给线程函数。

  1. void spellcheck(CDocument *p, string slocale, bool igncase);
  2.  
  3. std::thread thr(spellcheck, pd, "en_UK"true);

上面的范例启动在启动一个新线程时初始化,在某些情况下,你想要创建一个“空白”线程,并且不想马上启动它。嗯~~虽然复制线程是不允许的(这样做没什么意义),但你可以移动一个活动线程到“空白”线程,象这样:

  1. std::thread thr(spellcheck,pd,"en_UK",true);
  2. std::thread thr2;  
  3. thr2=std::move(thr);

或干脆互换:

  1. std::swap(thr,thr2);

Join和Detach

启动一个线程后,你可以在进程里加入这个线程:通过join()成员函数

  1. std::thread thr(spellcheck);
  2. thr.join();

另外,如果你不想加入这个线程,你也可以通过调用detach()销毁它:

  1. std::thread thr(spellcheck);
  2. thr.detach();

每个线程被分配到一个唯一的ID,你可以用它来比较,排序或者保存到关联容器中。要获得现在线程的ID,使用get_id():

  1. thread::id sp_id;
  2. sp_id=thr.get_id();

数据保护

互斥体为每个线程提供"独享"保护,<mutex>头文件定义了两类互斥体:定时不定时互斥体,每一类都有一个递归非递归版本:

  • std::mutex
  • std::recursive_mutex
  • std::timed_mutex
  • std::recursive_timed_mutex

所有的互斥体都提供了锁定和解锁的成员函数。然而,更常见的方法是使用std::unique_lockstd::lock_guard类模板。这些模板利用了RAII语义(Resource Acquisition is Initialization),在初始化时锁定资源,销毁时释放资源。在下面的例子中,用lock_guard来获得对s的独享存取:

  1. std::mutex mtx;
  2. std::string s;
  3.  
  4. void f()
  5. {
  6.   std::lock_guard<std::mutex> lck(mtx); 
  7.   all_caps(s);
  8. // the mutex is released here

如果您正在寻找一个更复杂的锁机制,支持延迟锁定和超时,请使用unique_lock代替。下面的代码试图使用定时锁定资源,锁定行为只等待10毫秒,否则函数f()放弃并退出:

  1. #include <date_time> //a new C++0x library
  2. #include <mutex>
  3.  
  4. std::timed_mutex mtx;
  5. std::string s;
  6.  
  7. void f()
  8. {
  9. std::unique_lock <std::timed_mutex>
  10.  lck(mtx,std::chrono::milliseconds(10));//wait up to 10ms 
  11.  if(lck) // did the lock succeed?
  12.    all_caps(s);
  13. // the mutex is released here

挖掘thread库

这些例子只是一个开胃菜,新的线程库提供的远远超过这些。举例来说,std::condition_variable可以让线程休眠直到它收到另一线程的通知;确保在静态存储期间正确地初始化对象的附加设施如延迟锁和本地线程对象等。


PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条