因此,您可以创建一个std::future
,它在调用.get()
之前不工作:
auto f_deferred = std::async( std::launch::deferred, []{ std::cout << "I ran\n"; } );
你也可以写一个可等待的std::future
,并且可以在任何线程中的任何时候通过代码准备好:
std::packaged_task<void()> p( []( std::cout << "I also ran\n"; } );
auto f_waitable = p.get_future();
如果你调用f_deferred.wait_for(1ms)
,它不会等待。如果调用f_deferred.get()
,则执行您选择的lambda(在本例中,是打印"I ran\n"
的lambda)。
如果调用f_waitable.get()
,管理任务的代码无法知道有人在等待未来。但是如果调用f_deferred.wait(1ms);
,则会立即得到future_status::deferred
。
有没有办法把这两个结合起来?
一个具体的用例是线程池在人们排队任务时返回future。如果一个未排队的future是.get()
'd,我想使用被阻塞的线程来执行任务,而不是让它空闲。另一方面,我希望具有返回的期货的人能够确定任务是否完成,甚至等待有限的时间来完成任务。(如果你正在等待,我可以让你的线程在等待期间空闲)
如果做不到这一点,那么在即将到来的提案中是否有解决方案可以比让我的线程池返回一个具有所有限制的未来更好地解决这个问题?我听说未来是没有未来的,而未来所解决的问题有更好的解决方案。
2条答案
按热度按时间f45qwnt81#
我不确定这是否正是你所需要的,但它的目的是说明我在评论中提出的建议。至少,我希望它能给你一些想法来实现你需要的东西,如果它不能满足你的所有需求。
免责声明:这是非常粗糙的。很多事情当然可以做得更优雅和更有效。
这是我的CMakeLists.txt
9njqaruj2#
Taskflow实现了一个工作窃取调度器。
tf::Executor::corun等待子任务流完成,但不会阻塞工作线程。正在运行等待任务的工作线程然后开始从其他工作线程窃取作业。这发生在corun方法本身内部。
https://taskflow.github.io/
下面的代码创建了1000个任务,这些任务本身等待1000个其他任务完成。同时有2个线程在工作,没有死锁。