我有以下代码来运行定时线程:
// Method to invoke a request with a timeout.
bool devices::server::CDeviceServer::invokeWithTimeout(CDeviceClientRequest& request,
CDeviceServerResponse& response)
{
// Retrieve the timeout from the device.
int timeout = getTimeout();
timeout += 500; // Add 500ms to cover invocation time.
// Invoke the request within a timed thread.
boost::promise<void> boostPromise;
boost::unique_future<void> boostFuture = boostPromise.get_future();
boost::thread boostThread([&]()
{
invoke(request, response);
boostPromise.set_value();
});
// The thread has timed out, if the future is not ready.
return (boostFuture.wait_for(boost::chrono::milliseconds(timeout))
==
boost::future_status::ready);
}
这似乎没有问题,该函数在超时时返回false。
但是,然后调用的代码(通过invoke(request,response);)会抛出一个异常 杀死了申请。如果线程尚未完成,如何成功终止该线程,以及 消耗任何例外。
我尝试了以下内容:
// The thread has timed out, if the future is not ready.
bool completed = (boostFuture.wait_for(boost::chrono::milliseconds(timeout))
==
boost::future_status::ready);
if (!completed)
{
boostThread.interrupt();
}
return completed;
但这也会引发异常并导致应用程序崩溃。我需要一个完全安全的机制 如果已达到超时,则可以安全地终止定时线程。
答案 0 :(得分:1)
提升文档说明:
如果传递给boost :: thread构造函数的函数或可调用对象在调用时传播的异常不是boost :: thread_interrupted,则调用std :: terminate()。
你必须捕获异常并彻底退出线程(或抛出boost :: thread_interrupted)
答案 1 :(得分:0)
好的,我提出的解决方案代码是:
// Functor to help invoke the device method, inside a timed thread.
struct invoke_fn
{
void operator()(devices::server::CDeviceServer& server,
boost::promise<void>& boostPromise,
CDeviceClientRequest& request,
CDeviceServerResponse& response)
{
try
{
server.invoke(request, response);
boostPromise.set_value();
}
catch (devices::util::CDeviceException &e)
{
// Add any error to the response.
std::string message = devices::util::retrieveDeviceExceptionMessage(e);
response.set_errormessage(message);
}
catch (std::exception &e)
{
// Add any exception message to the response.
std::string message(e.what());
response.set_errormessage(message);
}
}
};
// Method to invoke a request with a timeout.
bool devices::server::CDeviceServer::invokeWithTimeout(CDeviceClientRequest& request,
CDeviceServerResponse& response)
{
// Retrieve the timeout from the device.
int timeout = getTimeout();
timeout += 500; // Add 500ms to cover invocation time.
// Invoke the request within a timed thread.
boost::promise<void> boostPromise;
boost::unique_future<void> boostFuture = boostPromise.get_future();
boost::thread boostThread([&]()
{
invoke_fn functor;
functor(*this,
boostPromise,
request,
response);
});
// The thread has timed out, if the future is not ready.
return (boostFuture.wait_for(boost::chrono::milliseconds(timeout))
==
boost::future_status::ready);
}