Я хочу вызвать метод foo()
с таймаутом (скажем, 1 минута). Если его выполнение стоит менее 1 минуты, верните результат. В противном случае будет выдано исключение. Вот код:
//PRINT "START" IN THE LOG
auto m = std::make_shared<std::mutex>();
auto cv = std::make_shared<std::condition_variable>();
auto ready = std::make_shared<bool>(false);
auto response = std::make_shared<TResponse>();
auto exception = std::make_shared<FooException>();
exception->Code = ErrorCode::None;
std::thread([=]
{
std::unique_lock<std::mutex> lk(*m);
cv->wait(lk, [=]{ return *ready; });
try
{
//PRINT "PROCESS" IN THE LOG
auto r = foo();
*response = std::move(r);
}
catch(const FooException& e)
{
*exception = std::move(e);
}
lk.unlock();
cv->notify_one();
}).detach();
std::unique_lock<std::mutex> lk(*m);
*ready = true;
cv->notify_one();
auto status = cv->wait_for(lk, std::chrono::seconds(60));
if (status == std::cv_status::timeout)
{
//PRINT "TIMEOUT" IN THE LOG
//throw timeout exception
}
else
{
//PRINT "FINISH" IN THE LOG
if (exception->Code == ErrorCode::None)
{
return *response;
}
else
{
throw *exception;
}
}
Вы можете видеть, что я добавляю журналы START / PROCESS / FINISH / TIMEOUT в коде, каждый раз, когда выполняется этот метод, я вижу шаблон START / PROCESS / FINISH или START / PROCESS / TIMEOUT в журналах. Тем не менее, иногда журналы запускаются / обрабатываются без каких-либо завершений / тайм-аутов. Я думаю, cv->wait_for
должен блокировать текущий поток максимум на 60 секунд, тогда он существует либо с TIMEOUT, либо с FINISH.
Метод foo()
содержит операции ввода-вывода диска с сетевыми дисками, которые иногда зависают более 1 часа (причина не связана с этим вопросом и не может быть решена сейчас), я попытался заменить foo
с нитью спит, все работает как положено. Что не так с этим кодом и как я могу улучшить это?