concurrency.h 1.7 KB
Newer Older
S
superjom 已提交
1 2
#ifndef VISUALDL_UTILS_CONCURRENCY_H
#define VISUALDL_UTILS_CONCURRENCY_H
S
superjom 已提交
3

S
superjom 已提交
4
#include <glog/logging.h>
S
superjom 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17
#include <chrono>
#include <memory>
#include <thread>
#include <vector>

namespace visualdl {
namespace cc {

/*
 * Run a task every `duration` milliseconds.
 * Each evoke will start a thread to do this asynchronously.
 */
struct PeriodExector {
S
superjom 已提交
18
  using task_t = std::function<bool()>;
S
superjom 已提交
19 20 21

  void Quit() {
    // TODO use some conditonal variable to help quit immediately.
S
Superjom 已提交
22
    // std::this_thread::sleep_for(std::chrono::milliseconds(200));
S
superjom 已提交
23 24 25
    quit = true;
  }

S
superjom 已提交
26 27
  void Start() { quit = false; }

S
superjom 已提交
28
  void operator()(task_t&& task, int msec) {
S
superjom 已提交
29 30
    const int interval = 500;

S
superjom 已提交
31
    auto task_wrapper = [=] {
S
superjom 已提交
32
      while (!quit) {
S
Superjom 已提交
33
        // task failed
S
superjom 已提交
34
        if (!task()) break;
S
superjom 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48
        // if the program is terminated, quit while as soon as possible.
        // this is just trick, but should works.
        if (msec > 1000) {
          int i;
          for (i = 0; i < msec / interval; i++) {
            if (quit) break;
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
          }
          std::this_thread::sleep_for(
              std::chrono::milliseconds(msec - i * interval));
          if (quit) break;
        } else {
          std::this_thread::sleep_for(std::chrono::milliseconds(msec));
        }
S
superjom 已提交
49
      }
S
superjom 已提交
50
      LOG(INFO) << "quit concurrent job";
S
superjom 已提交
51 52
    };
    threads_.emplace_back(std::thread(std::move(task_wrapper)));
S
superjom 已提交
53
    msec_ = msec;
S
superjom 已提交
54 55 56
  }

  ~PeriodExector() {
S
Superjom 已提交
57
    Quit();
S
superjom 已提交
58 59 60 61 62 63 64 65 66 67
    for (auto& t : threads_) {
      if (t.joinable()) {
        t.join();
      }
    }
  }

private:
  bool quit = false;
  std::vector<std::thread> threads_;
S
superjom 已提交
68
  int msec_;
S
superjom 已提交
69 70 71 72 73 74
};

}  // namespace cc
}  // namespace visualdl

#endif