|
@@ -0,0 +1,155 @@
|
|
|
+
|
|
|
+
|
|
|
+/* Thread_condition 是多线程的条件控制类,主要是控制线程的启停和退出
|
|
|
+ * 线程创建后,一般是循环运行,
|
|
|
+ * 为了防止线程暂满整个cpu,那么需要线程在不工作的是否进入等待状态。
|
|
|
+ * Thread_condition 就可以控制线程的运行状态。
|
|
|
+ *
|
|
|
+ std::atomic<bool> m_pass_ever //线程能否直接通过等待,对后面的线程也生效。
|
|
|
+ std::atomic<bool> m_pass_once //线程能否直接通过等待,一次(通过一次之后,wait里面自动改为false)
|
|
|
+ * 外部调用notify系列的函数,唤醒等待的线程,让线程执行功能函数。
|
|
|
+ * 如果需要线程循环多次执行功能函数,那么就使用 notify_all(true),后面的线程可以直接通过等待了。
|
|
|
+ * 再使用 notify_all(false) ,即可停止线程,让其继续等待。
|
|
|
+ * 如果只想要线程执行一次,那就使用 notify_all(false, true)
|
|
|
+ * 注:notify_all(false, true)和notify_one(false, true) 一样,只能让其中一个线程执行一次
|
|
|
+ *
|
|
|
+ * m_kill //是否杀死线程,让线程强制退出,
|
|
|
+ * 外部调用 kill_all() 函数,可以直接通知线程自动退出。
|
|
|
+ //杀死所有的线程,强制退出线程函数,只是操作受当前Thread_condition影响的所有线程
|
|
|
+ //唤醒所有线程,使其通过等待,但是不能运行功能函数,必须直接return
|
|
|
+ // 注:只是修改m_kill为true,需要线程函数实时检测kill的状态,来return线程。
|
|
|
+ // 通过等待之后,也要检查kill的状态,如果为真,那么就不能执行功能函数,应该直接return
|
|
|
+
|
|
|
+ 注:notify唤醒线程之后,wait里面的判断函数会重新判断。
|
|
|
+ */
|
|
|
+
|
|
|
+#include "thread_condition.h"
|
|
|
+
|
|
|
+Thread_condition::Thread_condition()
|
|
|
+{
|
|
|
+ m_kill = false;
|
|
|
+ m_pass_ever = false;
|
|
|
+ m_pass_once = false;
|
|
|
+}
|
|
|
+Thread_condition::~Thread_condition()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//无限等待,由 is_pass_wait 决定是否阻塞。
|
|
|
+//返回m_pass,
|
|
|
+bool Thread_condition::wait()
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_condition_variable.wait(loc,std::bind(is_pass_wait,this));
|
|
|
+ bool t_pass = is_pass_wait(this);
|
|
|
+ m_pass_once = false;
|
|
|
+ return t_pass;
|
|
|
+}
|
|
|
+//等待一定的时间(默认时间单位:毫秒ms),由 is_pass_wait 决定是否阻塞。
|
|
|
+//return:is_pass_wait的结果, true:线程直接通过等待,false:线程超时了,然后通过等待。
|
|
|
+//注意了:线程阻塞期间,是不会return的。
|
|
|
+bool Thread_condition::wait_for(unsigned int millisecond)
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_condition_variable.wait_for(loc, std::chrono::milliseconds(millisecond), std::bind(is_pass_wait, this));
|
|
|
+ bool t_pass = is_pass_wait(this);
|
|
|
+ m_pass_once = false;
|
|
|
+ return t_pass;
|
|
|
+}
|
|
|
+//等待一定的时间(时间单位可调),由 is_pass_wait 决定是否阻塞。
|
|
|
+//return:is_pass_wait的结果, true:线程直接通过等待,false:线程超时了,然后通过等待。
|
|
|
+//注意了:线程阻塞期间,是不会return的。
|
|
|
+template<typename _Rep, typename _Period>
|
|
|
+bool Thread_condition::wait_for_ex(const std::chrono::duration<_Rep, _Period>& time_duration)
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_condition_variable.wait_for(loc, std::chrono::duration<_Rep, _Period>(time_duration), std::bind(is_pass_wait, this));
|
|
|
+ bool t_pass = is_pass_wait(this);
|
|
|
+ m_pass_once = false;
|
|
|
+ return t_pass;
|
|
|
+}
|
|
|
+
|
|
|
+//唤醒已经阻塞的线程,唤醒一个线程
|
|
|
+//pass_ever 或者 pass_once 为真时,才能唤醒线程。都为假时,线程进入等待。
|
|
|
+void Thread_condition::notify_one(bool pass_ever, bool pass_once)
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_pass_ever = pass_ever;
|
|
|
+ m_pass_once = pass_once;
|
|
|
+ m_condition_variable.notify_one();
|
|
|
+}
|
|
|
+//唤醒已经阻塞的线程,唤醒全部线程
|
|
|
+//pass_ever 或者 pass_once 为真时,才能唤醒线程。都为假时,线程进入等待。
|
|
|
+void Thread_condition::notify_all(bool pass_ever, bool pass_once)
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_pass_ever = pass_ever;
|
|
|
+ m_pass_once = pass_once;
|
|
|
+ m_condition_variable.notify_all();
|
|
|
+}
|
|
|
+//注:notify_all(false, true)和notify_one(false, true) 一样,只能让其中一个线程执行一次
|
|
|
+
|
|
|
+
|
|
|
+//杀死所有的线程,强制退出线程函数,只是操作受当前Thread_condition影响的所有线程
|
|
|
+//唤醒所有线程,使其通过等待,但是不能运行功能函数,必须直接return
|
|
|
+// 注:只是修改m_kill为true,需要线程函数实时检测kill的状态,来return线程。
|
|
|
+// 通过等待之后,也要检查kill的状态,如果为真,那么就不能执行功能函数,应该直接return
|
|
|
+void Thread_condition::kill_all()
|
|
|
+{
|
|
|
+ std::unique_lock<std::mutex> loc(m_mutex);
|
|
|
+ m_kill = true;
|
|
|
+ m_condition_variable.notify_all();
|
|
|
+}
|
|
|
+
|
|
|
+//判断是否或者,return !m_kill
|
|
|
+bool Thread_condition::is_alive()
|
|
|
+{
|
|
|
+ return !m_kill;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool Thread_condition::get_kill()
|
|
|
+{
|
|
|
+ return m_kill;
|
|
|
+}
|
|
|
+bool Thread_condition::get_pass_ever()
|
|
|
+{
|
|
|
+ return m_pass_ever;
|
|
|
+}
|
|
|
+bool Thread_condition::get_pass_once()
|
|
|
+{
|
|
|
+ return m_pass_once;
|
|
|
+}
|
|
|
+void Thread_condition::set_kill(bool kill)
|
|
|
+{
|
|
|
+ m_kill = kill;
|
|
|
+}
|
|
|
+void Thread_condition::set_pass_ever(bool pass_ever)
|
|
|
+{
|
|
|
+ m_pass_ever = pass_ever;
|
|
|
+}
|
|
|
+void Thread_condition::set_pass_once(bool pass_once)
|
|
|
+{
|
|
|
+ m_pass_once = pass_once;
|
|
|
+}
|
|
|
+void Thread_condition::reset(bool kill, bool pass_ever, bool pass_once)
|
|
|
+{
|
|
|
+ m_kill = kill;
|
|
|
+ m_pass_ever = pass_ever;
|
|
|
+ m_pass_once = pass_once;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//判断线程是否可以通过等待,wait系列函数的判断标志
|
|
|
+//注:m_kill或者m_pass为真时,return true
|
|
|
+bool Thread_condition::is_pass_wait(Thread_condition * other)
|
|
|
+{
|
|
|
+ if ( other == NULL )
|
|
|
+ {
|
|
|
+ throw (other);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return (other->m_kill || other->m_pass_ever || other->m_pass_once);
|
|
|
+}
|
|
|
+
|