C++并发实战13:std::future、std::async、std::promise、std::packaged_task(三)

2014-11-24 03:30:33 · 作者: · 浏览: 2
omise ::set_value_at_thread_exit (void); // when T is void void set_exception_at_thread_exit (exception_ptr p);//设置异常到共享状态中,但是在线程结束时才使共享状态就绪 void swap (promise& x) noexcept;//交换两个promise对象的共享状态



2.5 shared_future和future的区别是:一个future对象和一个共享状态相关,且转移只能通过move语义。但是多个shared_future对象可以和共享状态相关(即多对一)。std::shared_future 与 std::future 类似,但是 std::shared_future 可以拷贝、多个 std::shared_future 可以共享某个共享状态的最终结果(即共享状态的某个值或者异常)。shared_future 可以通过某个 std::future 对象隐式转换(参见 std::shared_future 的构造函数),或者通过 std::future::share() 显示转换,无论哪种转换,被转换的那个 std::future 对象都会变为 not-valid.

shared_future() noexcept;
shared_future (const shared_future& x);
shared_future (shared_future&& x) noexcept;
shared_future (future
  
   && x) noexcept;
下面的成员函数和future差不多:
operator=
   赋值操作符,与 std::future 的赋值操作不同,std::shared_future 除了支持 move 赋值操作外,还支持普通的赋值操作。
get
   获取与该 std::shared_future 对象相关联的共享状态的值(或者异常)。
valid
   有效性检查。
wait
   等待与该 std::shared_future 对象相关联的共享状态的标志变为 ready。
wait_for
   等待与该 std::shared_future 对象相关联的共享状态的标志变为 ready。(等待一段时间,超过该时间段wait_for 返回。)
wait_until
   等待与该 std::shared_future 对象相关联的共享状态的标志变为 ready。(在某一时刻前等待,超过该时刻 wait_until 返回。)

  


3) 通常线程池采用模板实现时各线程执行的都是相同类型的任务,若采用packaged_task可以将不同类型的函数对象封转在其内部,每个线程取走一个packaged_task执行,那么线程池执行的任务可以不同。

下面是一个GUI中一个线程专门接收用户任务并压入任务队列,另一个线程专门执行用户任务

std::mutex m;
std::deque
  
    > tasks;
bool gui_shutdown_message_received();
void get_and_process_gui_message();
void gui_thread()
{
   while(!gui_shutdown_message_received())//不断获取用户任务
   {
      get_and_process_gui_message();
      std::packaged_task
   
     task; { std::lock_guard
    
      lk(m); if(tasks.empty()) continue; task=std::move(tasks.front());// tasks.pop_front(); } task(); } } std::thread gui_bg_thread(gui_thread); template
     
       std::future
      
        post_task_for_gui_thread(Func f)//添加任务 { std::packaged_task
       
         task(f); std::future
        
          res=task.get_future(); std::lock_guard
         
           lk(m); tasks.push_back(std::move(task));// return res; }