Почему мой поток вызывает функциональный объект, а не присваивает его возвращаемое значение будущему объекту моего packaged_task?
Я хочу узнать, как получить возвращаемое значение функции с помощью packaged_task.
В приведенном ниже коде я создаю поток, который выполняет мою функцию DoTask. Затем я связываю эту функцию с packaged_task и заставляю ее ждать, пока я связываю ее с myTask packaged_task. Я извлекаю будущий объект myTask. Теперь я разблокирую условную переменную в DoTask (notify_one), чтобы он завершился. Я делаю get() для будущего myTask, чтобы получить значение возвращаемого bool в DoTask.
Но вместо того, чтобы ждать возврата 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 ответ
У вас есть поток работает DoTask
и packaged_task дал указание запустить DoTask
, Вы никогда не выполняли задачу, поэтому следующие две вещи неверны:
- Поток никогда не прекратится;
- Будущее задачи никогда не будет удовлетворено.
Возможно, вы хотели вместо этого переместить-построить поток из упакованной задачи:
#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();
}
Вы можете увидеть примеры использования для std::packaged_task
в этой документации.
(Кстати ваш дополнительный блок области в DoTask
полностью излишним.)