为什么我的线程调用一个函数对象而不是将其返回值赋给我的packaged_task的future对象?

时间:2016-07-15 13:06:20

标签: c++ future stdthread packaged-task

我想学习如何使用packaged_task检索函数的返回值。

在下面的代码中,我创建了一个运行我的函数DoTask的线程。然后我将该函数绑定到packaged_task并让它等待我将它绑定到packaged_task myTask。我提取myTask的未来对象。现在我在DoTask(notify_one)上解除阻塞条件变量,让它运行完成。我在myTask的未来做一个get()来检索DoTask中返回bool的值。

但DoTask不是等待DoTask返回,而是输入执行“INVOKE a function object”并且get()永远不会被执行的代码。

什么使DoTask无法设置我期望的未来,而是调用函数对象?

#include "stdafx.h"
#include <future>
#include <memory>
#include <thread>
#include <condition_variable>
#include <mutex>

std::condition_variable notifyCondVar;
std::mutex mu;

bool DoTask() 
{
  {
    std::unique_lock< std::mutex > locker( mu );
    notifyCondVar.wait( locker );
  }
  return true;
}

int main()
{
  std::thread packageTaskThread( DoTask );
  std::packaged_task< bool() > myTask( std::bind( DoTask ) );
  std::future< bool > taskFuture = myTask.get_future();
  notifyCondVar.notify_one();
  bool okay = taskFuture.get();
  packageTaskThread.join();

  return 0;
}

1 个答案:

答案 0 :(得分:1)

您有一个运行DoTask的线程指示运行DoTask的packaged_task。你从未真正执行过任务,所以以下两件事是错误的:

  1. 线程永远不会终止;
  2. 任务的未来永远不会得到满足。
  3. 也许你打算从打包的任务中移动构造线程,而不是:

    #include <future>
    #include <memory>
    #include <thread>
    #include <condition_variable>
    #include <mutex>
    
    std::condition_variable notifyCondVar;
    std::mutex mu;
    
    bool DoTask() 
    {
      std::unique_lock<std::mutex> locker(mu);
      notifyCondVar.wait(locker);
    
      return true;
    }
    
    int main()
    {
      std::packaged_task<bool()> myTask([]() { return DoTask(); });
      std::future<bool> taskFuture = myTask.get_future();
    
      std::thread packageTaskThread(std::move(myTask));
    
      notifyCondVar.notify_one();
      bool okay = taskFuture.get();
    
      packageTaskThread.join();
    }
    

    您可以在this documentation中查看std::packaged_task的使用示例。

    (BTW DoTask中的额外范围块完全是多余的。)