标签: stdasync

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万
查看次数

我为什么要使用std :: async?

我正在尝试深入探索新C++ 11标准的所有选项,同时使用std :: async并阅读其定义,我注意到两件事,至少在linux下使用gcc 4.8.1:

  • 它被称为异步,但它有一个真正的"顺序行为",基本上在你调用与异步函数foo相关的未来的行中,程序会阻塞,直到执行foo它完成.
  • 它取决于与其他人完全相同的外部库,以及更好的非阻塞解决方案,这意味着pthread,如果你想使用std::async你需要pthread.

在这一点上,我很自然地问为什么选择std :: async甚至是一组简单的仿函数?这是一个根本无法扩展的解决方案,您调用的未来越多,您的程序响应就越少.

我错过了什么吗?你能展示一个被授予以异步,非阻塞方式执行的例子吗?

c++ asynchronous future c++11 stdasync

65
推荐指数
3
解决办法
6万
查看次数


我可以在不等待未来限制的情况下使用std :: async吗?

高级别
我想在异步模式下调用一些没有返回值的函数而不等待它们完成.如果我使用std :: async,则在任务结束之前,未来的对象不会被破坏,这使得调用在我的情况下不同步.

void sendMail(const std::string& address, const std::string& message)
{
    //sending the e-mail which takes some time...
}

myResonseType processRequest(args...)
{
    //Do some processing and valuate the address and the message...

    //Sending the e-mail async
    auto f = std::async(std::launch::async, sendMail, address, message);

    //returning the response ASAP to the client
    return myResponseType;

} //<-- I'm stuck here until the async call finish to allow f to be destructed.
  // gaining no benefit from the async call.
Run Code Online (Sandbox Code Playgroud)

我的问题是

  1. 有没有办法克服这个限制? …

c++ multithreading asynchronous c++11 stdasync

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

哪个std :: async实现使用线程池?

使用std::async而不是手动创建std::thread对象的优点之一应该是std::async可以使用封面下的线程池来避免超额配置问题.但是哪些实现这样做?我的理解是微软的实现确实如此,但这些其他async实现呢?

  • Gnu的libstdc ++
  • Gnu的libc ++
  • Just Software的库
  • 提升(为boost::thread::async,不std::async)

感谢您提供的任何信息.

c++ multithreading c++11 stdasync

39
推荐指数
1
解决办法
1万
查看次数

使用线程池合法的std :: async的Visual C++实现

VISUAL C++使用Windows线程池(Vista的CreateThreadpoolWork,如果可用,QueueUserWorkItem如果不)调用时std::asyncstd::launch::async.

池中的线程数是有限的.如果创建多个运行很长时间而没有休眠的任务(包括执行I/O),则队列中即将发生的任务将无法工作.

标准(我使用N4140)表示,借助std::asyncstd::launch::async

...调用INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)(20.9.2,30.3.1.2),好像在一个新的执行线程中,由一个线程对象表示,并调用在DECAY_COPY()被调用的线程中进行求值async.

(§30.6.8p3,强调我的.)

std::thread的构造函数创建了一个新线程等.

关于一般的线程,它说(§1.10p3):

实现应确保所有未阻塞的线程最终取得进展.[ 注意:标准库函数可能会静默阻塞I/O或锁定.执行环境中的因素(包括外部强加的线程优先级)可能会阻止实现对前进进度做出某些保证.- 结束说明 ]

如果我创建了一堆OS线程或std::threads,都执行一些非常长(或许是无限)的任务,它们都将被安排(至少在Windows上;不会弄乱优先级,亲和力等).如果我们将相同的任务安排到Windows线程池(或使用std::async(std::launch::async, ...)哪个任务),则在先前的任务完成之前,后续计划的任务将不会运行.

严格来说,这是合法的吗?什么"最终"意味着什么?


问题是如果首先安排的任务事实上是无限的,那么剩下的任务就不会运行.所以其他线程(不是OS线程,但根据as-if规则的"C++ - 线程")将无法取得进展.

有人可能会争辩说,如果代码具有无限循环,则行为是不确定的,因此它是合法的.

但我认为,我们不需要标准所说的有问题的无限循环导致UB实现这一点.访问易失性对象,执行原子操作和同步操作都是"禁用"循环终止假设的副作用.

(我有一堆执行以下lambda的异步调用

auto lambda = [&] {
    while (m.try_lock() == false) {
        for (size_t i = 0; i < (2 << 24); i++) {
            vi++;
        }
        vi = 0;
    }
};
Run Code Online (Sandbox Code Playgroud)

并且只有在用户输入时才会释放锁定.但是还有其他有效的合法无限循环.)

如果我安排了几个这样的任务,我在他们之后安排的任务就无法运行. …

c++ visual-c++ language-lawyer stdasync

27
推荐指数
1
解决办法
1801
查看次数

std :: async(std :: launch :: deferred)+ std :: future :: then的行为

延迟未来背后的想法(仅通过std::async使用std::launch::deferredflag 调用实现)是仅当有人试图等待或拉动未来的未来价值或例外时才调用回调.到那时,回调没有被执行.

如果我将续约延迟到延期的未来,会发生什么std::future::then?延迟的未来将丢失(then使未来无效),而是返回新的未来.

在这种情况下,根据标准,会发生什么?新的未来是一个延期的未来吗?会不会陷入僵局?最新文档中未解决此问题.

c++ concurrency stdasync c++17 std-future

21
推荐指数
1
解决办法
500
查看次数

如果没有这样做,函数如何在新线程上"好像"运行?

C++标准的每个[futures.async]/3项目1,当一个函数与启动策略一起f传递时,将"运行"就像在新的执行线程中一样".std::asyncstd::launch::asyncf

鉴于它f可以做任何事情,包括无限循环和永久阻塞,一个实现如何提供在f自己的线程上运行而不实际在自己的线程上运行它的行为?也就是说,一个实现如何利用标准提供的"仿佛"摆动空间?

c++ multithreading c++11 stdasync

19
推荐指数
3
解决办法
496
查看次数

std :: async有什么问题?

在C++ And Beyond 的这篇剪辑的开头附近,我听到了一些关于问题的内容std::async.我有两个问题:

  1. 对于初级开发人员,是否有一套规则用于做什么以及在使用时要避免什么std::async

  2. 这个视频有什么问题?它们与本文有关吗?

c++ multithreading c++11 stdasync

18
推荐指数
2
解决办法
4087
查看次数

与简单的分离线程相比,为什么std :: async会变慢?

我已经多次被告知,我应该使用参数std::async来解决火灾和遗忘类型的任务std::launch::async(所以它最好在新的执行线程上使用它).

在这些陈述的鼓励下,我想看看如何std::async比较:

  • 顺序执行
  • 一个简单的分离 std::thread
  • 我简单的异步"实现"

我天真的异步实现看起来像这样:

template <typename F, typename... Args>
auto myAsync(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
    std::packaged_task<decltype(f(args...))()> task(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
    auto future = task.get_future();

    std::thread thread(std::move(task));
    thread.detach();

    return future;
}
Run Code Online (Sandbox Code Playgroud)

没有看中这里,包函子fstd::packaged task与它的参数一起,启动它的一个新的std::thread被分离,并用返回std::future的任务.

现在代码测量执行时间std::chrono::high_resolution_clock:

int main(void)
{
    constexpr unsigned short TIMES = 1000;

    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < TIMES; ++i)
    {
        someTask();
    }
    auto dur = …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading asynchronous c++11 stdasync

18
推荐指数
2
解决办法
2531
查看次数