延迟未来背后的想法(仅通过std::async使用std::launch::deferredflag 调用实现)是仅当有人试图等待或拉动未来的未来价值或例外时才调用回调.到那时,回调没有被执行.
如果我将续约延迟到延期的未来,会发生什么std::future::then?延迟的未来将丢失(then使未来无效),而是返回新的未来.
在这种情况下,根据标准,会发生什么?新的未来是一个延期的未来吗?会不会陷入僵局?最新文档中未解决此问题.
我刚读过:
并注意到它有点陈旧,大多数答案都与2011年之前的C++有关.这些天我们有语法lambda,甚至可以推断出返回类型,所以懒惰的评估似乎归结为只是传递它们:而不是
auto x = foo();
Run Code Online (Sandbox Code Playgroud)
你执行
auto unevaluted_x = []() { return foo(); };
Run Code Online (Sandbox Code Playgroud)
然后评估您需要的时间/地点:
auto x = unevaluted_x();
Run Code Online (Sandbox Code Playgroud)
似乎没有更多的东西了.但是,其中一个答案建议使用带异步启动的期货.有人可以用C++或更抽象的方式列出为什么/如果期货对懒惰评估工作有重要意义吗?似乎期货很可能会被热切地评估,但简单地说,在另一个线程上,并且可能没有创建它们的任何优先级; 无论如何,它应该依赖于实现,对吧?
另外,还有其他现代C++构造在懒惰评估的背景下有用吗?
我有一个返回std::future. 我已经在实现中添加了一个缓存,如果不需要重新计算,我想选择立即返回一个值。
我怎样才能创造一个已经解决的未来?
// Class declarations shortened to minimal example to communicate intent
class MyClass {
Cache m_cache;
std::future<int> foo(int arg);
}
class Cache {
std::optional<int> get(int arg);
}
std::future<int> MyClass::foo(int arg) {
if (auto res = m_cache.get(arg)) {
// *res is my result
return std::future(*res); // ????? Doesn't work
}
// If the cache misses, we need to calculate it
// Fire up the ol' thread pool and get to work
return std::launch(std::launch::async /* ommited for brevity …Run Code Online (Sandbox Code Playgroud) 我有一个std::packaged_task包含lambda的lambda,它通过复制捕获变量.当这个std::packaged_task被删除,我希望在lambda里面的变量生活是破坏,但我注意到,如果我得到了相关std::future为此std::packaged_task,该future对象扩展拉姆达内部变量的生存期.
例如:
#include <iostream>
#include <future>
class Dummy
{
public:
Dummy() {std::cout << this << ": default constructed;" << std::endl;}
Dummy(const Dummy&) {std::cout << this << ": copy constructed;" << std::endl;}
Dummy(Dummy&&) {std::cout << this << ": move constructed;" << std::endl;}
~Dummy() {std::cout << this << ": destructed;" << std::endl;}
};
int main()
{
std::packaged_task<void()>* p_task;
{
Dummy ScopedDummy;
p_task = new std::packaged_task<void()>([ScopedDummy](){std::cout << "lambda call with: " << &ScopedDummy …Run Code Online (Sandbox Code Playgroud) 假设我有一个原型如下所示的函数,属于类container_class:
std::vector<int> container_class::func(int param);
Run Code Online (Sandbox Code Playgroud)
该函数可能会或可能不会在某些输入上产生无限循环; 无法确定哪些输入会导致成功,哪些输入会导致无限循环.该函数在一个库中,我没有源代码,也无法修改(这是一个bug,将在几个月内在下一个版本中修复,但是现在我需要一种方法来解决它),所以修改函数或类的解决方案将不起作用.
我尝试使用std::async和隔离函数std::future,并使用while循环来不断检查线程的状态:
container_class c();
long start = get_current_time(); //get the current time in ms
auto future = std::async(&container_class::func, &c, 2);
while(future.wait_for(0ms) != std::future_status::ready) {
if(get_current_time() - start > 1000) {
//forcibly terminate future
}
sleep(2);
}
Run Code Online (Sandbox Code Playgroud)
这段代码有很多问题.一个是我无法强制终止std::future对象(以及它所代表的线程).
在极端情况下,如果我找不到任何其他解决方案,我可以在自己的可执行文件中隔离该函数,运行它,然后检查其状态并适当地终止它.但是,我宁愿不这样做.
我怎么能做到这一点?有没有比我现在做的更好的方式?
我知道了future返回的原因std::async有一些特殊的共享状态,通过它wait on returned future发生在未来的析构函数中。但是当我们使用 时std::pakaged_task,它的未来不会表现出相同的行为。为了完成任务打包,你必须显式调用get()上future的对象packaged_task。
现在我的问题是:
std::async与std::packaged_task)的内部实现可能是什么?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) 给出以下源代码
#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <chrono>
int main() {
auto task = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
throw std::runtime_error("error");
});
try {
while (task.wait_for(std::chrono::seconds(0)) !=std::future_status::ready)
{
std::cout << "Not ready: " << std::endl;
}
task.get();
}
catch (const std::exception& e)
{
std::cout << "Valid: " << task.valid() << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望,该计划将回应Valid: 0.使用g ++ 6.2.0就是这种情况.但是,使用MS VS2015版本14.0.25431.01 Update 3时,响应为Valid: 1.将异常传播到主线程后,未来的状态不会失效.这是一个错误还是我在这里遇到了未定义的行为?
我正在包装要从.NET使用的C ++库。C ++ API中有返回的函数std::future。我想让.NET代理类返回System.Threading.Tasks.Task。
我想到了在C ++端添加一个替换方法,该方法除了方法参数外还将包含一个函数指针。然后,我可以启动一个新线程(std::async例如,使用)并等待std::future::get。一旦std::future::get返回,我可以调用传入的函数指针。在C#端,我会将指针传递给一个函数,该函数将完成返回的Task。就像是:
Task CallCpp(int a, int b) {
TaskCompletionSource<int> tcs;
Action callback = () => tcs.SetResult(0);
IntPtr callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
CppMethod(callbackPtr, a, b);
return tcs.Task;
}
[DllExport]
external void CppMethod(IntPtr callback, int a, int b);
Run Code Online (Sandbox Code Playgroud)
void CppMethod(void (*callback)(), int a, int b) {
std::future f = realmethod(a, b);
std::async([&]{ f.get; callback(); });
}
std::future realmethod(int a, int b);
Run Code Online (Sandbox Code Playgroud)
(是的,代码中有内存管理问题。尽管这样足以使您理解这个想法)
我的问题是通过使用std::promise通知关联吗? std::futurestd::condition_variable
我搜索的源代码std::promise并找到了该网站。但我没有看到std::promise已经std::condition_variable在其成员的数据。
我知道我可以std::future通过以下方式检查状态:
my_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready
但是根据cppreference.com, std::future::wait_for在某些情况下可能会阻止:
由于调度或资源争用延迟,此功能可能阻塞的时间超过timeout_duration。
还是timeout_duration0 还是这样吗?如果是这样,是否还有另一种以保证免等待的方式查询状态的方法?