标签: packaged-task

packaged_task和async有什么区别

在使用C++ 11的线程模型时,我注意到了这一点

std::packaged_task<int(int,int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
task(2,3);
std::cout << f.get() << '\n';
Run Code Online (Sandbox Code Playgroud)

auto f = std::async(std::launch::async, 
    [](int a, int b) { return a + b; }, 2, 3);
std::cout << f.get() << '\n';
Run Code Online (Sandbox Code Playgroud)

似乎做了完全相同的事情.据我所知,有可能是一个重大的区别,如果我跑std::asyncstd::launch::deferred,但有一个在这种情况下?

这两种方法有什么区别,更重要的是,我应该使用哪种用例?

c++ multithreading packaged-task c++11 stdasync

120
推荐指数
2
解决办法
2万
查看次数

何时使用async或packaged_task的承诺?

我应该什么时候使用std::promisestd::asyncstd::packaged_task?你能告诉我何时使用它们的实际例子吗?

c++ asynchronous future promise packaged-task

42
推荐指数
2
解决办法
6243
查看次数

std :: packaged_task没有违反破坏承诺?

在使用打包任务时,我遇到了一些非常奇怪的事情.当读取~packched_task时,我得到的印象是,如果a std::packaged_task在执行之前被销毁,那么承诺将被破坏并且尝试从未来获得结果应该抛出std::future_error.

但是,在Visual Studio 2013上,情况似乎并非如此.请使用以下代码:

#include <iostream>
#include <future>
#include <functional>

int main() {
    std::future<int> f;
    {
        std::packaged_task<int()> task([](){return 3; });
        f = task.get_future();
    }
    std::cout<<f.get()<<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我期待得到一个std::future_error开启,f.get()但它阻止,等待打包的任务被执行.

尝试另一个编译器:http://ideone.com/Wt0WOc确实扔了std::future_error("Broken promise")...

我是否在Visual Studio 2013中看到了一个错误或者我错过了什么?

c++ future packaged-task c++11 visual-studio-2013

15
推荐指数
2
解决办法
886
查看次数

使用std :: packaged_task(VS11)时std :: future仍然延迟

似乎除非你打电话给std::async一个std::future遗嘱永远不会被设置为任何其他状态,future_status::deferred除非你打电话getwait未来.即使任务已经运行并存储结果wait_for,它wait_until也将继续不阻止和返回future_status::deferred.

这是一个例子:

#include <future>

void main()
{
    auto func = []() { return 5; };
    auto asyncFuture = std::async(std::launch::async, func);
    auto status = asyncFuture.wait_for(std::chrono::seconds(0));   // timeout (1)

    auto deferredFuture = std::async(std::launch::deferred, func);
    status = deferredFuture.wait_for(std::chrono::seconds(0));     // deferred (2)

    std::packaged_task<int()> task(func);
    auto packagedTaskFuture = task.get_future();
    status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)

    task();

    status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
    packagedTaskFuture.wait();
    status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // ready (0) …
Run Code Online (Sandbox Code Playgroud)

c++ future packaged-task c++11 visual-studio-2012

9
推荐指数
1
解决办法
1500
查看次数

如何使用参数创建packaged_task?

这个关于期货,承诺打包任务的优秀教程之后,我达到了我想要准备自己的任务的地步

#include <iostream>
#include <future>
using namespace std;

int ackermann(int m, int n) {   // might take a while
    if(m==0) return n+1;
    if(n==0) return ackermann(m-1,1);
    return ackermann(m-1, ackermann(m, n-1));
}

int main () {
    packaged_task<int(int,int)> task1 { &ackermann, 3, 11 }; // <- error
    auto f1 = task1.get_future();
    thread th1 { move(task1) };                              // call
    cout << "  ack(3,11):" << f1.get() << endl;
    th1.join();
}
Run Code Online (Sandbox Code Playgroud)

至于我可以解密gcc-4.7.0错误消息,它期望参数不同吗?但是怎么样?我尝试缩短错误消息:

error: no matching function for …
Run Code Online (Sandbox Code Playgroud)

c++ future packaged-task c++11

8
推荐指数
1
解决办法
7146
查看次数

使用packaged_task和threads进行可能的数据竞争

我最近运行valgrind --tool=helgrind了我的项目并收到了一条警告"可能的数据竞争",我认为这是一个问题.但是,即使是这个简单的测试程序也会导致以下消息:

#include <iostream>
#include <thread>
#include <future>

int main()
{
   std::packaged_task<void()> task([]()
   {
      std::cout << "Hello\n"; // You can leave this out
   });
   auto future = task.get_future();
   std::thread(std::move(task)).detach();
   future.get();
}
Run Code Online (Sandbox Code Playgroud)

编译g++-4.9 -p -g -std=c++11 -pthread -O3 test.cpp,输出valgrind --tool=helgrind ./a.out是:

==12808== Helgrind, a thread error detector
==12808== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.
==12808== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==12808== Command: ./a.out
==12808== 
Hello …
Run Code Online (Sandbox Code Playgroud)

c++ valgrind pthreads packaged-task

8
推荐指数
1
解决办法
547
查看次数

从不从 std::packaged_task 检索 std::future 的结果是否安全?

std::future从 a创建 a 是否安全std::packaged_task,该 a 在单独的线程上执行,但并不总是检索其结果?

#include <future>
#include <thread>

class Result {
  Result() {}
  ~Result() {}
};

void foo() {
  std::packaged_task<Result()> task(..);
  auto future = task.get_future();
  std::thread thread(std::move(task), ...);
  thread.detach();
  if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) {
    auto result = future.get();  <--- Task didn't take too long, retrieve future result
    ...
  }
}  <--- Task is taking too long, just abort and never call future.get()
Run Code Online (Sandbox Code Playgroud)

它似乎适用于 Clang / libc++: ~Result()is Called on the returned result by the …

c++ packaged-task c++11 stdthread

7
推荐指数
1
解决办法
834
查看次数

为什么 std::future 从 std::packaged_task 和 std::async 返回的不同?

我知道了future返回的原因std::async有一些特殊的共享状态,通过它wait on returned future发生在未来的析构函数中。但是当我们使用 时std::pakaged_task,它的未来不会表现出相同的行为。为了完成任务打包,你必须显式调用get()future的对象packaged_task

现在我的问题是:

  1. 未来(思考std::asyncstd::packaged_task)的内部实现可能是什么?
  2. 为什么相同的行为不适用于futurereturn from std::packaged_task?或者,换句话说,相同的行为是如何停止的std::packaged_task future

要查看上下文,请查看以下代码:

它不会等待完成countdown任务。但是,如果我取消评论// int value = ret.get();,它就会结束countdown并且很明显,因为我们实际上是在阻止返回的未来。

    // 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, …
Run Code Online (Sandbox Code Playgroud)

c++ packaged-task stdasync c++14 std-future

7
推荐指数
2
解决办法
728
查看次数

为什么std :: packaged_task <void()>无效?

使用MSVC2012,

以下代码将按预期编译和运行

std::packaged_task< int() > task( []()->int{ std::cout << "hello world" << std::endl; return 0; } );
std::thread t( std::move(task) );
t.join();
Run Code Online (Sandbox Code Playgroud)

而以下代码将无法编译和运行

std::packaged_task< void() > task( [](){ std::cout << "hello world" << std::endl; } );
std::thread t( std::move(task) );
t.join();
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

编辑:作为一种解决方法,可以使用std :: promise在返回void的函数上获取std :: future

std::promise<void> promise;
auto future = promise.get_future();
std::thread thread( [](std::promise<void> &p){ std::cout << "hello world" << std::endl; p.set_value(); }, std::move(promise) );
future.wait();
Run Code Online (Sandbox Code Playgroud)

请注意,带有std :: thread的vs2012库中存在一个错误,它会强制您将promise作为l值引用传递并移动promise,如果按值传递promise或r-则不会编译价值参考.这应该是因为实现使用std :: bind(),它的行为不符合预期.

c++ packaged-task c++11

6
推荐指数
1
解决办法
2390
查看次数

是否有相同的packaged_task :: set_exception?

我的假设是packaged_task有一个promise底层.如果我的任务抛出异常,我该如何将其路由到关联的future?只有一个promise我可以打电话set_exception - 我该如何做同样的事情packaged_task

exception-handling future promise packaged-task c++11

6
推荐指数
1
解决办法
790
查看次数