std :: async监视线程年龄

时间:2018-09-17 05:28:08

标签: c++ multithreading future

我正在通过(线程安全的)队列获取请求。每个请求都需要在单独的线程中处理。该函数(实际上是通过_popen调用Java程序并轮询其输出)可能会花费很长时间。从主线程中,我需要一种机制来指示这种情况(基本上是测量线程的运行时间)。

在我的示例中,我尝试使用一些时间信息来“丰富” std::future。该示例可以无缝运行,但是我不确定这是否是正确的方法。另外,即使这是“正确”的方式,我也无法为CFutureTest编写一个复制构造函数和一个赋值运算符,而我想控制自己。

这是一个非常简单的演示,模仿了我想要实现的目标:

typedef std::future<int> FutureResultInt;

int ThreadFunc() {
  std::random_device rd;
  std::mt19937 mt(rd());
  const int iRand = std::uniform_int_distribution<int>(2000, 6000)(mt);
  std::cout << "ThreadFunc waiting for [" << iRand << "] ms ... " << std::endl;
  std::this_thread::sleep_for(std::chrono::milliseconds(iRand));
  std::cout << "ThreadFunc [" << iRand << "] done" << std::endl;
  return iRand;
}

class CFutureTest {
 public:
  CFutureTest() = delete;
  CFutureTest(FutureResultInt&& fr)
      : m_start(std::chrono::system_clock::now()), m_result() {
    m_result = std::move(fr);
  };

  int GetAge() const {
    return std::chrono::duration_cast<std::chrono::milliseconds>(
               std::chrono::system_clock::now() - m_start)
        .count();
  }

  // private:
  FutureResultInt m_result;
  std::chrono::time_point<std::chrono::system_clock> m_start;
};

int main() {
  std::vector<CFutureTest> futures;
  for (int i = 0; i < 5; i++)
    futures.push_back(std::move(std::async(std::launch::async, ThreadFunc)));
  while (futures.size() > 0) {
    for (std::vector<CFutureTest>::iterator it = futures.begin();
         it != futures.end(); ++it) {
      CFutureTest& future = *it;
      const std::future_status stat =
          future.m_result.wait_for(std::chrono::milliseconds(1));
      switch (stat) {
        case std::future_status::timeout:
          if (future.GetAge() > 4000) {
            std::cout << "Thread has exceeded the time limit" << std::endl;
          }
          continue;
        case std::future_status::deferred:
          std::cout << "std::future_status::deferred" << std::endl;
          continue;
      }
      const int iResult = future.m_result.get();
      std::cout << "future returned [" << iResult << "] (removing!)"
                << std::endl;
      futures.erase(it);
      if (futures.size() < 1) break;
      it = futures.begin();
    }
  }
  return 0;
}

0 个答案:

没有答案