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

在下面的代码中,我创建一个运行我的函数DoTask的线程。然后,我将该函数绑定(bind)到packaged_task,并等待它绑定(bind)到packaged_task myTask。我提取myTask的 future 对象。现在,我取消阻止DoTask(notify_one)上的条件变量,以使其运行完成。我对myTask的 future 进行get()检索DoTask中return bool的值。

但是,DoTask不需要等待DoTask返回,而是输入执行“调用函数对象”的代码,并且永远不会执行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;
}

最佳答案

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

  • 线程将永远不会终止;
  • 将永远无法满足任务的 future 。

  • 也许您打算从打包的任务中移动构造线程,而不是:
    #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的用法示例。

    (顺便说一下,您在DoTask中的额外作用域块是完全多余的。)

    09-10 17:35