理解多线程及其同步、互斥等通信方式是理解现代操作系统的关键一环,当我们精通了Win32多线程程序设计后,理解和学习其它操作系统的多任务控制也非常容易。因此,学习Win32多线程不仅对理解Win32本身有重要意义,而且对学习和领会其它操作系统也有触类旁通的作用。
BOOL EnumProcesses(DWORD * lpidProcess, DWORD cb, DWORD*cbNeeded); |
DWORD GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule,LPTSTR lpstrFileName, DWORD nsize); |
UINT ThreadFunction(LPVOID pParam) { //线程处理代码 return0; } |
while(1) { WaitForSingleObject(…,…);//或WaitForMultipleObjects(…) //Do something } |
#include "windows.h" #include <process.h> class ExampleTask { public: void taskmain(LPVOID param); void StartTask(); }; void ExampleTask::taskmain(LPVOID param) {} void ExampleTask::StartTask() { _beginthread(taskmain,0,NULL); } int main(int argc, char* argv[]) { ExampleTask realTimeTask; realTimeTask.StartTask(); return 0; } |
error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)' None of the functions with this name in scope match the target type |
#include "windows.h" #include <process.h> class ExampleTask { public: void taskmain(LPVOID param); }; void ExampleTask::taskmain(LPVOID param) {} int main(int argc, char* argv[]) { ExampleTask realTimeTask; _beginthread(ExampleTask::taskmain,0,NULL); return 0; } |
error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)' None of the functions with this name in scope match the target type |
#include "windows.h" #include <process.h> class ExampleTask { public: void static taskmain(LPVOID param); void StartTask(); }; void ExampleTask::taskmain(LPVOID param) {} void ExampleTask::StartTask() { _beginthread(taskmain,0,NULL); } int main(int argc, char* argv[]) { ExampleTask realTimeTask; realTimeTask.StartTask(); return 0; } 和 #include "windows.h" #include <process.h> class ExampleTask { public: void static taskmain(LPVOID param); }; void ExampleTask::taskmain(LPVOID param) {} int main(int argc, char* argv[]) { _beginthread(ExampleTask::taskmain,0,NULL); return 0; } |
#include "windows.h" #include <process.h> class ExampleTask { public: friend void taskmain(LPVOID param); void StartTask(); }; void taskmain(LPVOID param) { ExampleTask * pTaskMain = (ExampleTask *) param; //通过pTaskMain指针引用 } void ExampleTask::StartTask() { _beginthread(taskmain,0,this); } int main(int argc, char* argv[]) { ExampleTask realTimeTask; realTimeTask.StartTask(); return 0; } |
int var; //全局变量 UINT ThreadFunction(LPVOIDpParam) { var = 0; while (var < MaxValue) { //线程处理 ::InterlockedIncrement(long*) &var); } return 0; } 请看下列程序: int globalFlag = false; DWORD WINAPI ThreadFunc(LPVOID n) { Sleep(2000); globalFlag = true; return 0; } int main() { HANDLE hThrd; DWORD threadId; hThrd = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &threadId); if (hThrd) { printf("Thread launched\n"); CloseHandle(hThrd); } while (!globalFlag) ; printf("exit\n"); } |
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL BOOL bManualReset, // 手动/自动 // TRUE:在WaitForSingleObject后必须手动调用ResetEvent清除信号 // FALSE:在WaitForSingleObject后,系统自动清除事件信号 BOOL bInitialState, //初始状态 LPCTSTR lpName //事件的名称 ); |
CWinThread *AfxBeginThread( AFX_THREADPROC pfnThreadProc, //控制函数 LPVOID pParam, //传递给控制函数的参数 int nPriority = THREAD_PRIORITY_NORMAL, //线程的优先级 UINT nStackSize = 0, //线程的堆栈大小 DWORD dwCreateFlags = 0, //线程的创建标志 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //线程的安全属性 ); |
//线程控制函数 UINT MfcThreadProc(LPVOID lpParam) { CExampleClass *lpObject = (CExampleClass*)lpParam; if (lpObject == NULL || !lpObject->IsKindof(RUNTIME_CLASS(CExampleClass))) return - 1; //输入参数非法 //线程成功启动 while (1) { ...// } return 0; } //在MFC程序中启动线程 AfxBeginThread(MfcThreadProc, lpObject); |
class CWinThread : public CCmdTarget { DECLARE_DYNAMIC(CWinThread) public: // Constructors CWinThread(); BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL); // Attributes CWnd* m_pMainWnd; // main window (usually same AfxGetApp()->m_pMainWnd) CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd) BOOL m_bAutoDelete; // enables 'delete this' after thread termination // only valid while running HANDLE m_hThread; // this thread's HANDLE operator HANDLE() const; DWORD m_nThreadID; // this thread's ID int GetThreadPriority(); BOOL SetThreadPriority(int nPriority); // Operations DWORD SuspendThread(); DWORD ResumeThread(); BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam); // Overridables //执行线程实例初始化,必须重写 virtual BOOL InitInstance(); // running and idle processing //控制线程的函数,包含消息泵,一般不重写 virtual int Run(); //消息调度到TranslateMessage和DispatchMessage之前对其进行筛选, //通常不重写 virtual BOOL PreTranslateMessage(MSG* pMsg); virtual BOOL PumpMessage(); // low level message pump //执行线程特定的闲置时间处理,通常不重写 virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing virtual BOOL IsIdleMessage(MSG* pMsg); // checks for special messages //线程终止时执行清除,通常需要重写 virtual int ExitInstance(); // default will 'delete this' //截获由线程的消息和命令处理程序引发的未处理异常,通常不重写 virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg); // Advanced: handling messages sent to message filter hook virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg); // Advanced: virtual access to m_pMainWnd virtual CWnd* GetMainWnd(); // Implementation public: virtual ~CWinThread(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; int m_nDisablePumpCount; // Diagnostic trap to detect illegal re-entrancy #endif void CommonConstruct(); virtual void Delete(); // 'delete this' only if m_bAutoDelete == TRUE // message pump for Run MSG m_msgCur; // current message public: // constructor used by implementation of AfxBeginThread CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam); // valid after construction LPVOID m_pThreadParams; // generic parameters passed to starting function AFX_THREADPROC m_pfnThreadProc; // set after OLE is initialized void (AFXAPI* m_lpfnOleTermOrFreeLib)(BOOL, BOOL); COleMessageFilter* m_pMessageFilter; protected: CPoint m_ptCursorLast; // last mouse position UINT m_nMsgLast; // last mouse message BOOL DispatchThreadMessageEx(MSG* msg); // helper void DispatchThreadMessage(MSG* msg); // obsolete }; |
CWinThread *AfxBeginThread( //从CWinThread派生的类的 RUNTIME_CLASS CRuntimeClass *pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); |
///////////////////////////////////////////////////////////////////////////// // CMyUIThread thread class CMyUIThread : public CWinThread { DECLARE_DYNCREATE(CMyUIThread) protected: CMyUIThread(); // protected constructor used by dynamic creation // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyUIThread) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL // Implementation protected: virtual ~CMyUIThread(); // Generated message map functions //{{AFX_MSG(CMyUIThread) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CMyUIThread IMPLEMENT_DYNCREATE(CMyUIThread, CWinThread) CMyUIThread::CMyUIThread() {} CMyUIThread::~CMyUIThread() {} BOOL CMyUIThread::InitInstance() { // TODO: perform and per-thread initialization here return TRUE; } int CMyUIThread::ExitInstance() { // TODO: perform any per-thread cleanup here return CWinThread::ExitInstance(); } BEGIN_MESSAGE_MAP(CMyUIThread, CWinThread) //{{AFX_MSG_MAP(CMyUIThread) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() |
CMyUIThread *pThread; pThread = (CMyUIThread*) AfxBeginThread( RUNTIME_CLASS(CMyUIThread) ); |
void AfxEndThread( UINT nExitCode //the exit code of the thread ); |
HADLE CreateFile(PCTSTR lpFileName, //通信端口名,如"COM1" WORD dwDesiredAccess, //对资源的访问类型 WORD dwShareMode, //指定共享模式,COM不能共享,该参数为0 PSECURITY_ATTRIBUTES lpSecurityAttributes, //安全描述符指针,可为NULL WORD dwCreationDisposition, //创建方式 WORD dwFlagsAndAttributes, //文件属性,可为NULL HANDLE hTemplateFile //模板文件句柄,置为NULL ); |
BOOL WINAPI GetCommState( HANDLE hFile, //标识通信端口的句柄 LPDCB lpDCB //指向一个设备控制块(DCB结构)的指针 ); |
BOOL SetCommState( HANDLE hFile, //标识通信端口的句柄 LPDCB lpDCB //指向一个设备控制块(DCB结构)的指针 ); |
typedef struct _DCB { // dcb DWORD DCBlength; // sizeof(DCB) DWORD BaudRate; // current baud rate DWORD fBinary: 1; // binary mode, no EOF check DWORD fParity: 1; // enable parity checking DWORD fOutxCtsFlow: 1; // CTS output flow control DWORD fOutxDsrFlow: 1; // DSR output flow control DWORD fDtrControl: 2; // DTR flow control type DWORD fDsrSensitivity: 1; // DSR sensitivity DWORD fTXContinueOnXoff: 1; // XOFF continues Tx DWORD fOutX: 1; // XON/XOFF out flow control DWORD fInX: 1; // XON/XOFF in flow control DWORD fErrorChar: 1; // enable error replacement DWORD fNull: 1; // enable null stripping DWORD fRtsControl: 2; // RTS flow control DWORD fAbortOnError: 1; // abort reads/writes on error DWORD fDummy2: 17; // reserved WORD wReserved; // not currently used WORD XonLim; // transmit XON threshold WORD XoffLim; // transmit XOFF threshold BYTE ByteSize; // number of bits/byte, 4-8 BYTE Parity; // 0-4=no,odd,even,mark,space BYTE StopBits; // 0,1,2 = 1, 1.5, 2 char XonChar; // Tx and Rx XON character char XoffChar; // Tx and Rx XOFF character char ErrorChar; // error replacement character char EofChar; // end of input character char EvtChar; // received event character WORD wReserved1; // reserved; do not use } DCB; |
BOOL SetCommMask( HANDLE hFile, //标识通信端口的句柄 DWORD dwEvtMask //能够使能的通信事件 ); |
值 | 事件描述 |
EV_BREAK | A break was detected on input. |
EV_CTS | The CTS (clear-to-send) signal changed state. |
EV_DSR | The DSR(data-set-ready) signal changed state. |
EV_ERR | A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY. |
EV_RING | A ring indicator was detected. |
EV_RLSD | The RLSD (receive-line-signal-detect) signal changed state. |
EV_RXCHAR | A character was received and placed in the input buffer. |
EV_RXFLAG | The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function. |
EV_TXEMPTY | The last character in the output buffer was sent. |
BOOL WaitCommEvent( HANDLE hFile, //标识通信端口的句柄 LPDWORD lpEvtMask, //指向存放事件标识变量的指针 LPOVERLAPPED lpOverlapped, // 指向overlapped结构 ); |