简体   繁体   English

什么时候使用 std::launch::deferred?

[英]When to use std::launch::deferred?

Lines from Anthony William book:安东尼威廉书中的台词:

std::launch::deferred indicates that the function call is to be deferred until either wait() or get() is called on the future. std::launch::deferred指示 function 调用将被推迟,直到将来调用wait()get()为止。

 X baz(X&); auto f7 = std::async(std::launch::deferred, baz, std::ref(x)); //run in wait() or get() //... f7.wait(); //invoke deferred function

What could be the benefits or differences of this code over a direct call ( baz(ref(x)) )?与直接调用 ( baz(ref(x)) ) 相比,这段代码的好处或区别是什么?

In other words, what's the point of having future here?换句话说,在这里拥有未来有什么意义?

Suppose you have a thread pool. 假设你有一个线程池。

The thread pool owns a certain number of threads. 线程池拥有一定数量的线程。 Say 10. 说10。

When you add tasks, they return a future, and they queue into the pool. 添加任务时,它们会返回未来,并且它们会排入池中。

Threads in the pool wake up, grab a task, work on it. 池中的线程唤醒,抓取任务,处理它。

What happens when you have 10 tasks in that pool waiting on a task later in the queue ? 当您在该池中有10个任务等待队列中的某个任务时会发生什么? Well, a deadlock. 好吧,陷入僵局。

Now, what if we return a deferred future from this pool. 现在,如果我们从此池中返回延迟的未来,该怎么办?

When you wait on this deferred future it wakes up, checks if the task is done. 当你等待这个延期的未来它醒来时,检查任务是否完成。 If so, it finishes and returns. 如果是这样,它就会完成并返回。

Next, if the tasks is in the queue and not yet started, it steals the work from the queue and runs it right there , and returns. 接下来,如果任务在队列中但尚未启动,它会从队列中窃取工作并在那里运行 ,然后返回。

Finally, if it is being run by the queue but not finished, it does something more complex. 最后,如果它是由队列运行但没有完成,它会做一些更复杂的事情。 (the simplest version which usually works is that it blocks on the task, but that doesn't solve some pathological cases). (通常最常用的最简单的版本是阻止任务,但这并不能解决某些病态情况)。

In any case, now if a task in the queue sleeps waits for another task in the queue to complete that isn't queue'd yet, we still get forward progress. 在任何情况下,现在如果队列中的任务休眠等待队列中的另一个任务完成但尚未排队,我们仍然可以取得进展。


Another use of this is less arcane. 另一个用途是减少奥术。 Suppose we have some lazy values. 假设我们有一些懒惰的值。

Instead of calculating them, we store shared futures with the calcuation steps in them. 我们不是计算它们,而是将共享期货与其中的计算步骤一起存储。 Now anyone who needs them just does a .get() . 现在任何需要它们的人只需要一个.get() If the value has already been calculated, we get the value; 如果已经计算了该值,我们得到该值; otherwise, we calculate it, then get it. 否则,我们计算它,然后得到它。

Later, we add in a system to do some work on idle or in another thread. 稍后,我们添加一个系统来做空闲或另一个线程的工作。 These replace said deferred lazy futures in some cases, but not in others. 在某些情况下,这些取代了延迟的懒惰期货,但在其他情况下却没有。

I think, the main benefit is that it might be executed in a different thread - the one which actually reads the future. 我认为,主要的好处是它可能在不同的线程中执行 - 实际上是未来的线程。 This allows to transfer 'units of work' between threads - ie thread 1 creates the future, while thread 2 calls wait on it. 这允许在线程之间传输“工作单元” - 即线程1创建未来,而线程2调用wait它。

in my point of view.在我看来。 I read effective modern c++ rule 35我阅读了effective modern c++规则 35

Compared to thread-based programming, a task-based design spares you the travails
of manual thread management

it means std::launch::deferred is a worse case when the OS have no ability to allocate a new thread for you however, the baz function still work but it run as a deferred task instead of returning failed like pthread_create or throw exception with std::thread like this:这意味着 std::launch::deferred 是一个更糟糕的情况,当操作系统无法为您分配新线程时, baz function 仍然可以工作,但它作为延迟任务运行,而不是像pthread_create那样返回失败或抛出异常std::thread 像这样:

terminate called after throwing an instance of 'std::system_error'
  what():  Resource temporarily unavailable

conclusion:结论:

// same thread with called.
    std::async(std::launch::deferred, bax,..) = baz() 

// create a new thread to run baz(..) in case of OS have ability to allocate a new thread, otherwise same above 
    std::async(baz, ...) = std::async(std::launch::deferred| std::launch::async , baz, ...) != baz() ;

https://man7.org/linux/man-pages/man3/pthread_create.3p.htmlhttps://man7.org/linux/man-pages/man3/pthread_create.3p.html
tested at https://godbolt.org/z/hYv7TW51qhttps://godbolt.org/z/hYv7TW51q测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: async - std :: launch :: async | 的std ::推出::推迟 - std::async - std::launch::async | std::launch::deferred std :: async(std :: launch :: deferred)+ std :: future :: then的行为 - behaviour of std::async(std::launch::deferred) + std::future::then 默认启动策略和std :: launch :: deferred之间的区别 - Difference between default launch policy and std::launch::deferred 使用 std::launch::deferred 不会推迟 std::async 中的 function - using std::launch::deferred does not defer the function in std::async 具有自动 (launch::async|launch::deferred) 启动策略的 std::async 的语义是什么? - What is the semantics of std::async with automatic (launch::async|launch::deferred) launch policy? 我什么时候需要使用std :: async(std :: launch :: async,func())而不是func()? - When should I need to use std::async(std::launch::async, func()) instead of func()? 在c ++ 11中如何使用std :: async和std :: launch :: any - In c++11 how to use std::async with std::launch::any 指定launch :: async时,std :: async不执行 - std::async not executing when specifying launch::async 将std :: async与std :: launch :: async结合使用时的奇怪行为 - Strange behaviour when using std::async with std::launch::async 使用std :: packaged_task(VS11)时std :: future仍然延迟 - std::future still deferred when using std::packaged_task (VS11)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM