#include "threadcontroller.h" #include #if defined(Q_OS_WIN32) #include #include #endif #include /* 获取线程数 */ int ThreadUtility::GetThreadCount(int processID) { #if defined(Q_OS_WIN32) PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (hProcessSnap == INVALID_HANDLE_VALUE) { qDebug()<<"CreateToolhelp32Snapshot 调用失败"; return -1; } BOOL bMore = ::Process32First(hProcessSnap, &pe32); //printf("%-30s %-20s %-20s %-15s\n","szExeFile","th32ProcessID","th32ParentProcessID","cntThreads"); while(bMore) { //printf("%-30s ",pe32.szExeFile); //printf("%-20d ",pe32.th32ProcessID); //printf("%-20d",pe32.th32ParentProcessID); ////显示进程的线程数 //printf("%-15d\n",pe32.cntThreads); //int pid = getpid(); bMore = Process32Next(hProcessSnap, &pe32); if(static_cast(pe32.th32ProcessID) == processID) { //qDebug()<<"进程名称 = "<terminate(); if(!thread->wait(20000)) qDebug()<<"线程terminate异常"; } else { qDebug()<<"线程正常结束"<start(); moveToThread(pHostThread); /* 将本实例移动到新线程中,其实就是将事件循环等移过去 */ m_pWorkTimer->moveToThread(pHostThread); /* 将定时器移到新线程中,定时器触发的槽函数就会运行在新线程中 */ /*---------------------------------------------------------------- * 对线程执行quit会发生: 结束线程的事件循环(线程里的对象不再能接受任何信号, 除了deleteLater), 发送finished信号 * 宿主线程对象和工作对象都在同一个线程, 所以用DirectConnection * 这里是一个序列: 对线程执行quit -> 线程发送finished信号 -> 工作对象释放 -> 线程对象释放 ----------------------------------------------------------------*/ connect(pHostThread, &QThread::finished, this, &ThreadWorker::deleteLater, Qt::DirectConnection); connect(this, &ThreadWorker::destroyed, pHostThread, &QThread::deleteLater, Qt::DirectConnection); WorkerCollector::Instance()->AddWorker(this); } ThreadWorker::~ThreadWorker() { } //在子线程执行(m_pWorkTimer已被移至线程) void ThreadWorker::OnStartWorkTimer(int msecs) { m_nInterval = (msecs==-1)?10:msecs; if(msecs == -1) m_pWorkTimer->setSingleShot(true); m_pWorkTimer->start(0); } //Start方法被主线程调用, 内容在主线程执行 void ThreadWorker::Start(int interval) { QMutexLocker lockerInited(&m_mutexInited); m_bInited = false; emit sig_StartWorkTimer(interval); } void ThreadWorker::NonBlockStop() { QThread *pThread = dynamic_cast(thread()); if(pThread == nullptr) return; pThread->quit(); pThread->requestInterruption(); } //该方法只能被主线程调用 //否则报错: Thread tried to wait on itself bool ThreadWorker::BlockStop(unsigned long msecs) { return ThreadUtility::BlockExitThread(thread(), msecs);; } void ThreadWorker::SetInterval(int interval) { m_pWorkTimer->setInterval(interval); } //OnWorkTimer在其他线程执行 void ThreadWorker::OnWorkTimer() { m_pWorkTimer->setInterval(m_nInterval); /* 初始化锁 */ m_mutexInited.lock(); if(!m_bInited) { m_bInited = true; DoInit(); } m_mutexInited.unlock(); DoWork(); emit sig_Ticked(this); //工作对象非循环且内容执行完毕 if(m_pWorkTimer->isSingleShot()) { NonBlockStop(); return; } //主动调用NonBlockStop或BlockStop且未等待超时 if(thread()->isInterruptionRequested()) { m_pWorkTimer->stop(); return; } } WorkerCollector::CollectorGarbo WorkerCollector::garbo; WorkerCollector* WorkerCollector::sm_pInstance = new WorkerCollector(); //初始化静态单例(饿汉) //在这里释放那些: 直到程序结束还没有被释放的工作对象 WorkerCollector::~WorkerCollector() { sm_pInstance = nullptr; auto pred = [](QPointer x){return x != nullptr;}; QList> remainWorkers; std::copy_if(m_listWorkers.begin(), m_listWorkers.end(), std::back_inserter(remainWorkers), pred); qDebug() << "线程管理器释放: 待释放工作对象个数" << remainWorkers.count(); int counter = 0; for(QPointer pWorker: remainWorkers) { //注意: 这里如果是停止超时的情况, 说明工作对象正在执行内容, 直接调用delete可能会导致崩溃 //而且这里不能使用deleteLater来释放工作对象, 因为线程的事件循环已经退出了 if(!pWorker->BlockStop(5000)) continue; delete pWorker; counter++; } qDebug()<<"已释放工作对象: "< pWorker(worker); m_listWorkers.append(pWorker); }