#ifndef MYSEM_H_XZL_201808141050 #define MYSEM_H_XZL_201808141050 #include #include #include enum { SEMPHORE_FAIL = (-1), SEMPHORE_SUCCESS = 0, SEMPHORE_TIME_OUT = 1 }; class Semphore { public: Semphore(const int sigs = 0) : m_signals(sigs), m_blocked(0) {} ~Semphore() {} private: Semphore(const Semphore &) = delete; Semphore(Semphore &&) = delete; Semphore operator=(const Semphore &) = delete; private: std::mutex m_mtx; std::condition_variable m_cv; int m_signals; int m_blocked; public: int wait(const int time_out_ms = (-1)) { std::unique_lock ul(m_mtx); if (m_signals > 0) { --m_signals; return SEMPHORE_SUCCESS; } else { ++m_blocked; } if (time_out_ms >= 0) { std::chrono::milliseconds wait_time_ms(time_out_ms); auto result = m_cv.wait_for(ul, wait_time_ms, [&] { return m_signals > 0; }); --m_blocked; if (result) { --m_signals; return SEMPHORE_SUCCESS; } else { return SEMPHORE_TIME_OUT; } } else { m_cv.wait(ul, [&] { return m_signals > 0; }); --m_blocked; --m_signals; return SEMPHORE_SUCCESS; } } inline void signal(const int count = 1) { std::lock_guard lg(m_mtx); m_signals += count; if (m_blocked > 0) { m_cv.notify_one(); } } }; #endif