| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | 
							- /*----------------------------------------------------------------
 
-  *      概述
 
-  * 1, 使用movetothread的方式执行工作线程(因为这种方式是官方推荐)
 
-  * 2, 这种方式可以同时实现线程主动运行并且可以接收到Qt的事件循环
 
-  * ----------------------------------------------------------------
 
-  *      使用流程
 
-  * 1, 提供一个ThreadWorker类作为工作对象的基类, 工作对象继承它之后, 实现DoWork纯虚函数, 在函数里编写工作内容
 
-  * 2, 提供一个ThreadController类作为线程管理器的基类, 管理器继承它之后, 可以使用AddWorker方法传入工作对象, 管理器释放后会自动释放未停止的工作对象
 
-  * 3, 工作对象调用Start并传入循环间隔来开启线程
 
-  * 4, 工作对象调用BlockStop/NonBlockStop来阻塞/非阻塞地停止
 
-  * ----------------------------------------------------------------
 
-  *      特性
 
-  * 1, 代码分离, 使用者只要考虑实现工作内容, 工作对象的线程相关操作全部在基类实现
 
-  * 2, 阻塞/非阻塞两种方式停止线程, 停止时, 先释放工作对象再释放宿主线程
 
-  * 3, 当工作内容是无限阻塞, 可以使用阻塞方式并设置阻塞超时来停止线程, 但是工作对象不会被释放
 
-  * 4, 工作对象支持事件循环, 例如在woker实现类里使用tcp对象并监听readyRead信号
 
-  * 5, 非循环工作的工作对象执行完毕后, 自动释放, 宿主线程也会退出
 
-  * 6, 程序退出时, 阻塞式(可设置超时)释放所有未被释放的工作对象和宿主线程(不包括异常停止的工作对象)
 
-  * 7, 工作对象支持循环执行和单次执行
 
-  * 8, 这两种停止情况都能正常工作: dowork正在执行时; dowork的timer间隔期间
 
-  * 9, 支持外部监听工作对象被释放事件
 
- ----------------------------------------------------------------*/
 
- #ifndef THREADUTILITY_H
 
- #define THREADUTILITY_H
 
- #include <QMutex>
 
- #include <QObject>
 
- #include <QPointer>
 
- #include <QThread>
 
- #include <QTimer>
 
- #include <QWaitCondition>
 
- /**
 
-  * @brief 这个函数是获取一些线程的状态
 
-  * 
 
-  */
 
- class ThreadUtility
 
- {
 
- public:
 
-     static int GetThreadCount(int processID);           /* 获取线程数 */
 
-     static bool BlockExitThread(QThread *thread, unsigned long msecs = ULONG_MAX);
 
- };
 
- /**
 
-  * 工作线程
 
- */
 
- class ThreadWorker : public QObject
 
- {
 
-     Q_OBJECT
 
- public:
 
-     explicit ThreadWorker();
 
-     virtual ~ThreadWorker();
 
-     virtual void Start(int interval = -1);
 
-     virtual void NonBlockStop();
 
-     virtual bool BlockStop(unsigned long msecs = ULONG_MAX);
 
-     void SetInterval(int interval);
 
- protected:
 
-     virtual void DoInit() = 0;
 
-     virtual void DoWork() = 0;              /* 重写此函数,即可运行在新的线程中 */
 
- private slots:
 
-     void OnWorkTimer();                     /* OnWorkTimer在其新线程执行 */
 
-     void OnStartWorkTimer(int msecs);
 
- signals:
 
-     void sig_Ticked(ThreadWorker *self);
 
-     void sig_StartWorkTimer(int msecs);
 
- private:
 
-     QTimer *m_pWorkTimer;
 
-     bool m_bInited;
 
-     QMutex m_mutexInited;
 
-     int m_nInterval;
 
- };
 
- /**
 
-  * 控制线程
 
- */
 
- class WorkerCollector : public QObject
 
- {
 
-     Q_OBJECT
 
- public:
 
-     static WorkerCollector* Instance(){return sm_pInstance;}
 
-     ~WorkerCollector();
 
-     void AddWorker(ThreadWorker *worker);
 
- private:
 
-     WorkerCollector(){}
 
-     //防拷贝, C++11
 
-     WorkerCollector(WorkerCollector const&) = delete;
 
- 	WorkerCollector& operator=(WorkerCollector const&) = delete;
 
- private:
 
-     static WorkerCollector* sm_pInstance;     //单例实例
 
-     QList<QPointer<ThreadWorker>> m_listWorkers;    //包含所有的工作对象
 
-     
 
-     /*----------------------------------------------------------------
 
-      * 关于释放全局单例: 
 
-      * 一个妥善的方法是让这个类自己知道在合适的时候把自己删除; 或者说把删除自己的操作挂在系统中的某个合适的点上, 使其在恰当的时候自动被执行;
 
-      * 程序在结束的时候, 系统会自动析构所有的全局变量;事实上, 系统也会析构所有的类的静态成员变量, 就像这些静态成员也是全局变量一样;
 
-      * 利用这个特征, 我们可以在单例类中定义一个这样的静态成员变量, 而它的唯一工作就是在析构函数中删除单例类的实例;
 
-     ----------------------------------------------------------------*/
 
- private:
 
-     class CollectorGarbo
 
-     {
 
-     public:
 
-         ~CollectorGarbo()
 
-         {  
 
-             if (WorkerCollector::sm_pInstance != nullptr)
 
-                 delete WorkerCollector::sm_pInstance;
 
-         }
 
-     };
 
-     static CollectorGarbo garbo;
 
-     /*----------------------------------------------------------------*/
 
- };
 
- #endif // THREADUTILITY_H
 
 
  |