У меня есть простой планировщик задач: вызывается метод execute, а packaged_task
возвращает указатель на мой Task
. Когда задача завершилась, мне нужно показать данные отладки (графический интерфейс задействован, поэтому мне нужно сделать это в основном потоке). Я бы хотел использовать boost::wait_for_any
для этого, как показано, однако j->get()
иногда выдает исключение boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::promise_already_satisfied> >
. Это оставляет мне две мысли. Либо это из-за копирования, которое указывает класс исключения, но я бы не видел, где это происходит, или из-за того, что он уже вызван get
, что не может произойти, поскольку фьючерсы видны только в этом блоке методов, и я уже преобразовал их в shared_futrues поэтому он должен работать.правильное использование boost :: wait_for_any
Так что в части wait_for_any
, как бы я вернул указатель на экземпляр Task
, который закончился?
Редактировать используя future
вместо shared_future
.
Выключено исключение было брошено в функцию execute
одной из моих задач, и фьючерсы будут нести эти исключения до вызова get
. Сам код был прав (за исключением отсутствующего обработчика исключений). Однако использование сигналов усиления (см. Ответ ниже) может быть лучше.
std::vector<boost::future<Task*>> futures;
std::vector<Task*> tasks = get_tasks();
for (Task* t : tasks) {
typedef boost::packaged_task<Task*()> task_t;
task_t task([t]() -> Task* {
t->execute();
return t;
});
auto fut = task.get_future();
futures.push_back(std::move(fut));
impl->io_service.post(boost::bind(&task_t::operator(), boost::make_shared<task_t>(std::move(task))));
}
for (Task* t : tasks) {
auto j = boost::wait_for_any(futures.begin(), futures.end());
Task* task = j->get();
task->display_debug();
futures.erase(j);
}
В случае, если вы заинтересованы, вот подобная демонстрация с использованием сигналов Повысьте эффективность: ** [Live On Coliru] (http://coliru.stacked-crooked.com/ a/f155fdcc19f25400) ** – sehe
Оказывается, исключение было выбрано в функцию 'execute' одной из моих задач, и фьючерсы будут нести эти исключения до вызова' get'. Сам код был прав (за исключением отсутствующего обработчика исключений). Однако использование сигналов усиления может быть лучше. – Mene