超出范围时,从std :: async返回的std :: future挂起

Gam*_*ads 1 c++ c++11 stdasync std-future

我使用的组合std::asyncstd::futureC++ 11.我正在使用对我在代码中执行的某项活动强制执行time_out,这可能需要一些时间,因为我尝试连接到服务器.

以下是代码:

#include <future>
#include <chrono>

std::size_t PotentiallyLongRunningActivity() {
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(10000s);
    return 10;
}

bool DoActivity() {

  bool activity_done = false;
  auto my_future_result(std::async(std::launch::async, []() {
      return PotentiallyLongRunningActivity(); //returns size_t
  }));

  std::future_status my_future_status = my_future_result.wait_for(std::chrono::milliseconds(800));
  if (my_future_status == std::future_status::timeout) {
      activity_done = false;
  }
  else if (my_future_status == std::future_status::ready) {
      if (my_future_result.valid() && my_future_result.get() > 0) {
          activity_done = true;
      }
  }

  return activity_done;
  //my_future_result hangs while exiting this method !!!
}

int main(int argc, char *argv[])
{
    DoActivity();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,事情都很好.在许多情况下,未来会超时并且已经准备就绪.但是,我观察到的奇怪行为是在某些情况下UI会挂起,因为my_future_result当超出范围时会挂起.我通过重复my_future_result.get()在退出方法之前调用时永远不会返回的调用来确认这一点.

我怎么能绕过这个?有什么方法可以取消,删除或终止std::future

Mik*_*l F 6

您在std::async任务完成之前退出了您的功能.在某些情况下,一个std::future意志的析构函数会阻塞,直到任务完成.

http://en.cppreference.com/w/cpp/thread/future/wait_for

此处wait_for的示例文档显示了wait_for超时后的多次调用,表明超时行为不会取消std::async任务.

没有内置支持(我可以发现)允许线程被外部杀死.这是有道理的,因为如果以这种方式终止线程,则无法正确清理线程使用的系统资源的状态.

相反,最好将超时逻辑放在线程本身中,以便它可以自行终止并正确清理.