- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我才知道原因future
从 std::async
返回有一些特殊的共享状态,通过它 wait on returned future
发生在 future 的析构函数中。但是当我们使用 std::pakaged_task
,它的 future 不会表现出相同的行为。
要完成打包任务,您必须明确调用 get()
在 future
来自 packaged_task
的对象.
现在我的问题是:
std::async
vs std::packaged_task
)? future
从 std::packaged_task
返回?或者,换句话说,对于 std::packaged_task
相同的行为是如何停止的? future
? countdown
任务。但是,如果我取消评论
// int value = ret.get();
,它会完成
countdown
并且很明显,因为我们实际上是在阻止返回的 future 。
// packaged_task example
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!" <<std::endl;
return from-to;
}
int main ()
{
std::cout << "Start " << std::endl;
std::packaged_task<int(int,int)> tsk (countdown); // set up packaged_task
std::future<int> ret = tsk.get_future(); // get future
std::thread th (std::move(tsk),10,0); // spawn thread to count down from 10 to 0
// int value = ret.get(); // wait for the task to finish and get result
std::cout << "The countdown lasted for " << std::endl;//<< value << " seconds.\n";
th.detach();
return 0;
}
如果我使用
std::async
执行任务
countdown
在另一个线程上,无论我是否使用
get()
在返回
future
对象与否,它将始终完成任务。
// packaged_task example
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!" <<std::endl;
return from-to;
}
int main ()
{
std::cout << "Start " << std::endl;
std::packaged_task<int(int,int)> tsk (countdown); // set up packaged_task
std::future<int> ret = tsk.get_future(); // get future
auto fut = std::async(std::move(tsk), 10, 0);
// int value = fut.get(); // wait for the task to finish and get result
std::cout << "The countdown lasted for " << std::endl;//<< value << " seconds.\n";
return 0;
}
最佳答案
std::async
对所给任务的执行方式和地点有明确的了解。那就是它的工作:执行任务。要做到这一点,它实际上必须把它放在某个地方。某个地方可能是一个线程池,一个新创建的线程,或者在一个被破坏 future
的人执行的地方。 .
因为 async
知道函数将如何执行,它拥有构建一种机制所需的 100% 的信息,该机制可以在潜在的异步执行结束时进行通信,并确保如果您破坏了 future
,那么将执行该函数的任何机制最终都会实际执行它。毕竟,它知道那个机制是什么。
但是packaged_task
没有。全部 packaged_task
do 是存储一个可以使用给定参数调用的可调用对象,创建一个 promise
与函数返回值的类型,并提供一种方法来获得 future
并执行生成值的函数。
任务实际执行的时间和地点不是 packaged_task
的事。如果没有这些知识,同步需要做 future
的析构函数与任务同步根本无法构建。
假设您想在新创建的线程上执行任务。好的,因此将其执行与 future
同步的破坏,你需要一个互斥锁,析构函数将阻塞它直到任务线程完成。
但是如果你想在与 future
的调用者相同的线程中执行任务怎么办?的析构函数?那么,你不能使用互斥锁来同步它,因为它都在同一个线程上。相反,您需要让析构函数调用任务。这是一种完全不同的机制,取决于您计划如何执行。
因为 packaged_task
不知道您打算如何执行它,它无法执行任何操作。
请注意,这不是 packaged_task
独有的。 .全部 future
从用户创建的 promise
创建的对象将不具有 async
的特殊属性的 future
s。
所以问题真的应该是为什么async
以这种方式工作,而不是为什么其他人不这样做。
如果你想知道,那是因为两个相互竞争的需求:async
需要是一种高级的、脑死亡的简单方法来获得异步执行(对于这种情况下同步销毁是有意义的),并且没有人想要创建一个新的 future
除了其析构函数的行为外,类型与现有类型相同。所以他们决定如何重载future
工作,使其实现和使用复杂化。
关于c++ - 为什么 std::future 从 std::packaged_task 和 std::async 返回的不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63843676/
正在关注 this excellent tutorial对于futures、promises 和打包任务,我到了要准备自己的任务的地步 #include #include using namesp
在下面的程序中,我试图创建一个带有成员函数的 packaged_task: #include using namespace std; struct S { int calc(int& a)
我天真地期望它能编译: template auto run(Func && func) { auto package = std::packaged_task{std::forward(fu
我正在尝试使用这样的仿函数创建一个打包任务: Worker w(someString, anotherString, i*length,length); boost::packaged_task ta
我试图绕过 std::packaged_task 缺少复制构造函数的问题,以便我可以将它传递给 std::function(它只会被移动)。 我继承自 std::packaged_task 并添加了一
嗨,我不知道如何编写一个正确的队列绑定(bind)并执行传递给方法 OCRQueue::enqueue() 的 lambda 表达式 // the task queue std::queue > ta
编译下面的程序时,出现错误信息: 错误 1 错误 C2228:'.get_future' 的左侧必须具有类/结构/union c:\users\haliaga\documents\visual s
我正在分析以下代码片段并试图详细理解它: template auto ThreadPool::add( FUNCTION&& Function, ARGUMENTS&&... Arguments )
我从 http://en.cppreference.com/w/cpp/thread/packaged_task 中的部分代码中复制了一个奇怪的核心转储, #include #include #i
我正在尝试采用 std::async 风格的“任务”并将其存储在容器中。我必须克服困难才能实现它,但我认为一定有更好的方法。 std::vector> mTasks; template std::fu
我最近在我的项目上运行 valgrind --tool=helgrind 并收到警告“可能的数据竞争”,我认为这是令人担忧的。然而,即使是这个简单的测试程序也会导致此消息: #include #in
我正在尝试使用 packaged_task 实现异步。我正在通过一个模板化函数 bsync 来尝试这个。 bsync 接受 2 个参数:一个函数 f 和一个参数包 args,并返回一个 future
我一直在寻找 problem of type-erasing a std::packaged_task using std::function 的解决方法. 我想做的是这样的: #include #
我正在玩 Antony Williams - C++ Concurrency in Action 一书中的示例 4.14,其中使用 std::packaged_task 和 std::thread 模
我试图将 std::packaged_task 包装在另一个类中,以便与任务调度程序一起使用。 目前,除了 std::future 支持外,我的一切都正常工作。为了获得 std::future 支持,
我正在尝试围绕 Glib::Dispatcher 构建一些包装器,以将任何功能类型分派(dispatch)到分派(dispatch)器中。我想要一些可以将函数传输到 Glib 主循环中的函数分派(di
std::packaged_task 模板有一个接受分配器的构造函数: packaged_task pt {allocator_arg_t, a, f}; 我想问: 1) 它的存在表明 package
是否有一种标准方法可以将 std::packaged_task 添加到现有线程?在任务运行之前必须发生大量开销,所以我想这样做一次,然后保持线程运行并等待任务执行。我希望能够使用 futures,这样
我正在尝试将 packaged_task 包装在 lambda 中,以便将它们存放在容器中。我在下面写了一个测试代码来模拟包装和调用 lambda 函数。我的代码如下: int test() {
在使用 C++11 的线程模型时,我注意到 std::packaged_task task([](int a, int b) { return a + b; }); auto f = task.get
我是一名优秀的程序员,十分优秀!