【发布时间】:2021-01-21 02:47:15
【问题描述】:
我想要达到的目标是让程序停止进程并在进程超过超时时间时返回超时错误。
我从second most voted answer to this question 获得了超时功能。我遇到了一个错误,指出 std::result_of_t 在 c++17 中已弃用,所以我使用建议的替换 std::invoke_result_t 重新创建它并像这样实现它:
template <typename TF, typename TDuration, class... TArgs>
std::invote_result_t<TF&&, TArgs&&...> run_with_timeout(TF&& f, TDuration timeout, TArgs&&... args)
{
using R = std::invoke_result_t<TF&&, TArgs&&...>;
std::packaged_task<R(TArgs...)> task(f);
auto future = task.get_future();
std::thread thr(std::move(task), std::forward<TArgs>(args)...);
if (future.wait_for(timeout) != std::future_status::timeout)
{
thr.join();
return future.get(); // this will propagate exception from f() if any
}
else
{
thr.detach(); // we leave the thread still running
throw std::runtime_error("Timeout");
}
}
我想用它来检查类方法函数的超时。所以我尝试以类似的方式使用它:
template <typename TF, typename TDuration, class... TArgs>
std::invote_result_t<TF&&, TArgs&&...> ClassOne::run_with_timeout(TF&& f, TDuration timeout, TArgs&&... args)
{
using R = std::invoke_result_t<TF&&, TArgs&&...>;
std::packaged_task<R(TArgs...)> task(f);
auto future = task.get_future();
std::thread thr(std::move(task), std::forward<TArgs>(args)...);
if (future.wait_for(timeout) != std::future_status::timeout)
{
thr.join();
return future.get(); // this will propagate exception from f() if any
}
else
{
thr.detach(); // we leave the thread still running
throw std::runtime_error("Timeout");
}
}
// The function checked for timeout
int ClassOne::func(ClassTwo *param1, std::string name)
{
// Some code here...
// For mimicking function process:
std::this_thread::sleep_for(10s);
return 0;
}
// Function which calls the timed process with timeout function
int ClassOne::dummy(ClassTwo *param1, std::string name)
{
int retVal = 0; // zero for no error, non-zero for error
try
{
retVal = run_with_timeout(func, 20s, param1, name);
}
catch (runtime_error & e)
{
return 1;
}
}
有了这个,我得到了错误:
no instance of function template "ClassOne::run_with_timeout" matches the argument list
argument types are: (int (ClassTwo *param1, std::string target), std::chrono::seconds, ClassTwo *, std::string)
我认为问题类似于this entry,但我不知道如何纠正它。我需要使用超时函数的一些函数具有不同的对象参数,这就是使用函数模板的原因。
非常感谢您的帮助!
【问题讨论】:
-
您的
func是静态的吗?如果不是,则需要将指向ClassOne对象(例如this)的指针作为第一个参数传递。 -
@Botje
func不是静态的。如果不是太多,你能用上面的代码作为参考的例子来详细说明一下吗? run_with_timeout 函数模板会是什么样子?如何在 run_with_timeout 中调用 ClassOne::func?template <class TC, typename TF, typename TDuration, class... TArgs> std::invote_result_t<TF&&, TArgs&&...> ClassOne::run_with_timeout(TC *className, TF&& f, TDuration timeout, TArgs&&... args)上面的代码哪里错了?非常感谢!
标签: c++ templates timeout c++17 member-functions