use*_*257 4 c++ thread-safety packaged-task
我正在尝试围绕 Glib::Dispatcher 构建一些包装器,以将任何功能类型分派到调度程序中。我想要一些可以将函数传输到 Glib 主循环的函数调度:
template<class Function, class ...Args>
std::future<typename std::result_of<Function(Args...)>::type>
dispatch(Function &&f, Args &&...args);
Run Code Online (Sandbox Code Playgroud)
这个函数将从 f(args) 创建一个打包的任务并返回它的未来:
std::packaged_task<typename std::result_of<Function(Args...)>::type()> task(f(args...));
return task.get_future();
Run Code Online (Sandbox Code Playgroud)
我现在需要从这个任务 a 创建std::packaged_task<void()>将它们放入一个 std::queue 以便连接到 Glib::Dispatcher 的函数可以执行它们。
我的问题是:如何从一个创建std::packaged_task<R()>一个std::packaged_task<void()>在两个步骤,这样我可以从第一个任务返回它的未来,并把第二个进入队列std::queue<std::packaged_task<void()>>类型?
首先,要std::packaged_task调用具有给定参数集的特定函数,则 (a) 您需要将函数绑定到参数,然后再将其传递给std::packaged_task,或者 (b) 您需要将参数传递给std::packaged_task目的。在您的代码中,您正在传递f(args...)给std::packaged_task构造函数,该构造函数将在那里调用函数,然后将结果传递给构造函数,这可能不是您想要的,甚至可能无法编译。
其次,如果您在构造时绑定参数,那么您的std::packaged_task实例是一个不带参数并返回的可调用对象void,因此可以直接移动到std::packaged_task<void()>.
把这一切放在一起,我们得到:
std::queue<std::packaged_task<void()>> task_queue;
template<class Function, class ...Args>
std::future<typename std::result_of<Function(Args...)>::type>
dispatch(Function &&f, Args &&...args) {
std::packaged_task<typename std::result_of<Function(Args...)>::type()> task(
std::bind(f,args...));
auto res=task.get_future();
task_queue.push(std::packaged_task<void()>(std::move(task)));
return res;
}
Run Code Online (Sandbox Code Playgroud)