功能:
1.各个进程启动、挂起、恢复、停止等
2.监听进程的运行状态,进程退出(正常、非正常)时,通知用户
3.异步队列
4.线程安全
进程管理器类:
#ifndef __ProcessManager_ProcessManager_H__ #define __ProcessManager_ProcessManager_H__#include "Process.h"#define PROCESSMANAGER_AUTO_MUTEX boost::recursive_mutex PROCESSMANAGER_AUTO_MUTEX_NAME; #define PROCESSMANAGER_LOCK_AUTO_MUTEX boost::recursive_mutex::scoped_lock AutoMutexLock(PROCESSMANAGER_AUTO_MUTEX_NAME);/** Process Manager */ class ProcessManager : public QObject, public Singleton<ProcessManager> {Q_OBJECT public:/** Default constructor.*/ProcessManager(Log* pLog);/** Default destructor.*/~ProcessManager(void);public:/** start*/Process* Start(const string& strName, const string& strCmdLine, bool bShowWnd = true);/** suspend*/void Suspend(Process* pProc);/** resume*/void Resume(Process* pProc);/** stop*/void Stop(Process* pProc);/** suspend all*/void SuspendAll();/** resume all*/void ResumeAll();/** stop all*/void StopAll();/** Override standard Singleton retrieval.*/static ProcessManager& GetSingleton(void);/** Override standard Singleton retrieval.*/static ProcessManager* GetSingletonPtr(void);protected slots:/** Notify finish*/void _NoifyFinished(Process* pProc);Q_SIGNALS:/** Fire finish*/void _FireFinished(const string&);private:typedef map<string, Process*> ProcessMap;ProcessMap m_Processs;Log* m_pLog;PROCESSMANAGER_AUTO_MUTEX };#endif // __ProcessManager_ProcessManager_H__
#include "ProcessManager.h"//----------------------------------------------------------------------- template<> ProcessManager* Singleton<ProcessManager>::m_pSingleton = 0;ProcessManager* ProcessManager::GetSingletonPtr(void) {return m_pSingleton; }//----------------------------------------------------------------------- ProcessManager& ProcessManager::GetSingleton(void) { assert(m_pSingleton); return *m_pSingleton; }//----------------------------------------------------------------------- ProcessManager::ProcessManager(Log* pLog) {if (pLog == NULL){THROW_EXCEPTION("Log can not be null!", "ProcessManager");}m_pLog = pLog; }//----------------------------------------------------------------------- ProcessManager::~ProcessManager(void) {StopAll(); }//----------------------------------------------------------------------- Process* ProcessManager::Start( const string& strName, const string& strCmdLine, bool bShowWnd /*= true*/ ) {PROCESSMANAGER_LOCK_AUTO_MUTEXProcessMap::iterator i = m_Processs.find(strName);if (i != m_Processs.end()){return i->second;}else{Process* pProc = new Process(strName, m_pLog);connect(pProc, SIGNAL(_FireFinished(Process*)), this, SLOT(_NoifyFinished(Process*)), Qt::QueuedConnection);m_Processs[strName] = pProc;pProc->Start(strCmdLine, bShowWnd);return pProc;} }//----------------------------------------------------------------------- void ProcessManager::Suspend(Process* pProc) {PROCESSMANAGER_LOCK_AUTO_MUTEXpProc->Suspend(); }//----------------------------------------------------------------------- void ProcessManager::Resume(Process* pProc) {PROCESSMANAGER_LOCK_AUTO_MUTEXpProc->Resume(); }//----------------------------------------------------------------------- void ProcessManager::Stop(Process* pProc) {PROCESSMANAGER_LOCK_AUTO_MUTEXpProc->Stop(); }//----------------------------------------------------------------------- void ProcessManager::SuspendAll() {PROCESSMANAGER_LOCK_AUTO_MUTEXProcessMap::iterator i = m_Processs.begin();for ( ; i != m_Processs.end(); ++i){i->second->Suspend();} }//----------------------------------------------------------------------- void ProcessManager::ResumeAll() {PROCESSMANAGER_LOCK_AUTO_MUTEXProcessMap::iterator i = m_Processs.begin();for ( ; i != m_Processs.end(); ++i){i->second->Resume();} }//----------------------------------------------------------------------- void ProcessManager::StopAll() {PROCESSMANAGER_LOCK_AUTO_MUTEXProcessMap::iterator i = m_Processs.begin();for ( ; i != m_Processs.end(); ++i){i->second->Stop();} }//----------------------------------------------------------------------- void ProcessManager::_NoifyFinished(Process* pProc) {PROCESSMANAGER_LOCK_AUTO_MUTEXemit _FireFinished(pProc->GetName());ProcessMap::iterator i = m_Processs.find(pProc->GetName());if (i != m_Processs.end()){m_Processs.erase(i);}delete pProc; }
进程类:
#ifndef __ProcessManager_Process_H__ #define __ProcessManager_Process_H__#include "PreDefine.h"#define PROCESS_AUTO_MUTEX boost::recursive_mutex PROCESS_AUTO_MUTEX_NAME; #define PROCESS_LOCK_AUTO_MUTEX boost::recursive_mutex::scoped_lock AutoMutexLock(PROCESS_AUTO_MUTEX_NAME);/** Process */ class Process : public QObject {Q_OBJECTfriend class ProcessManager; protected:/** Default constructor - used by ProcessManager.Warning Do not call directly*/Process(const string& strName, Log* pLog);/** Default destructor.*/~Process();public:/** start process*/bool Start(const string& strCmdLine, bool bShowWnd = true);/** suspend process*/void Suspend();/** resume process */void Resume();/** stop process*/void Stop();/** is process runing*/bool IsRuning();/** get name*/string GetName();private:/** listen to process is stoped ?*/void Listener();Q_SIGNALS:/** Fire ProcessManager this process is stoped*/void _FireFinished(Process*);protected:/* Gets the last loading error*/string ProcessError(void);private:string m_strName;Log* m_pLog;HANDLE m_hPId;HANDLE m_hTId;boost::thread* m_pListener;PROCESS_AUTO_MUTEX };#endif // __ProcessManager_Process_H__
#include "Process.h"//----------------------------------------------------------------------- Process::Process(const string& strName, Log* pLog) {if (pLog == NULL){THROW_EXCEPTION("Log can not be null!", "Process");}m_strName = strName;m_pLog = pLog;m_hPId = NULL;m_hTId = NULL;m_pListener = NULL; }//----------------------------------------------------------------------- Process::~Process() {}//----------------------------------------------------------------------- bool Process::Start(const string& strCmdLine, bool bShowWnd /** = true */) {PROCESS_LOCK_AUTO_MUTEXif (m_hPId != NULL) {//logm_pLog->LogMessage("Process " + m_strName + " is started.", LMT_OUTBAR);return true;}//-----------Create Process----------- STARTUPINFOA si;ZeroMemory(&si, sizeof(STARTUPINFOA));si.cb = sizeof(STARTUPINFOA);si.dwFlags = STARTF_USESHOWWINDOW;si.wShowWindow = bShowWnd ? SW_SHOW : SW_HIDE;PROCESS_INFORMATION pi;ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));BOOL bSuccess = CreateProcessA(NULL, (LPSTR)(strCmdLine.c_str()), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);if (!bSuccess) {//logm_pLog->LogMessage("Could not start process " + m_strName + ". System Error: " + ProcessError(), LMT_OUTBAR);//notify process manager to remove meemit _FireFinished(this);return false;}//logm_pLog->LogMessage("Start process " + m_strName + " successful.", LMT_OUTBAR);m_hPId = pi.hProcess;m_hTId = pi.hThread;//-----------Listener-----------boost::function0<void> listenerFunc = boost::bind(&Process::Listener, this);m_pListener = new boost::thread(listenerFunc);//-----------Resume----------- ResumeThread(pi.hThread);WaitForInputIdle(pi.hProcess, 5000);return true; }//----------------------------------------------------------------------- void Process::Suspend() {PROCESS_LOCK_AUTO_MUTEXif (m_hPId == NULL) return;SuspendThread(m_hTId); }//----------------------------------------------------------------------- void Process::Resume() {PROCESS_LOCK_AUTO_MUTEXif (m_hPId == NULL) return;ResumeThread(m_hTId); }//----------------------------------------------------------------------- void Process::Stop() {PROCESS_LOCK_AUTO_MUTEXif (m_hPId == NULL) return;//Kill Listenerm_pListener->interrupt();m_pListener->detach();delete m_pListener;m_pListener = NULL;//Kill ProcessTerminateProcess(m_hPId, 0);m_hPId = NULL;m_hTId = NULL;//logm_pLog->LogMessage("Process " + m_strName + " is stoped.", LMT_OUTBAR);//notify process manager to remove meemit _FireFinished(this); }//----------------------------------------------------------------------- bool Process::IsRuning() {PROCESS_LOCK_AUTO_MUTEXif (m_hPId == NULL) return false;return true; }//----------------------------------------------------------------------- string Process::GetName() {return m_strName; }//----------------------------------------------------------------------- void Process::Listener() {try{WaitForSingleObject(m_hPId, INFINITE);{//local : avoid to always lock PROCESS_LOCK_AUTO_MUTEXm_pListener->detach();delete m_pListener;m_pListener = NULL;m_hPId = NULL;m_hTId = NULL;//logm_pLog->LogMessage("Process " + m_strName + " is stoped.", LMT_OUTBAR);//notify process manager to remove meemit _FireFinished(this);}}catch(const boost::thread_interrupted&){//interrupted }catch(...){//other } }string Process::ProcessError( void ) {LPVOID lpMsgBuf; FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL); string strError = (char*)lpMsgBuf;LocalFree(lpMsgBuf);return strError; }