标签:style blog http color io 使用 ar strong 文件
CEvent类:
1 CEvent( 2 3 BOOL bInitiallyOwn = FALSE, //FALSE未发信,禁止系统启动运行正在等待的线程 4 5 BOOL bManualReset = FALSE, //FALSE时自动发信 6 LPCTSTR lpszNAme = NULL, 7 8 LPSECURITY_ATTRIBUTES lpsaAttribute = NULL 9 10 );
注:
自动发信——初始状态FALSE(未发信),需要时,可用CEvent成员函数SetEvent设置为发信状态,从而使处于等待的线程队列中第一个线程恢复运行,但事件对象随即自动会把其状态变为FALSE.故自动事件对象一次只能启动一个处于等待的线程.
手动发信——手动事件对象,一旦用函数设置为"TRUE"发信状态,就一直处于有效状态.除非用对象的成员函数PlusEvent或ResetEvent把它重新设置为"FALSE"未发信状态。故可用于恢复多个处在等待状态的线程运行.
举个例子——自动事件对象的应用
程序主要功能描述:
点击启动线程,则会启动两个线程,均弹出消息框,单机确定后,线程被自身挂起,而后单机SetEvent按钮,设置为发信状态.按顺序重新启动被线程.
程序利用MFC对话框程序编写,主要功能代码如下:
/************************************************************************/ /* 全局事件对象 */ /************************************************************************/ CEvent g_eventObj; /************************************************************************/ /*作为子线程 */ /************************************************************************/ UINT MsgThread1(LPVOID pParam) { LPCWSTR pMsg = (LPCWSTR)pParam; CWnd* pMainWin = AfxGetMainWnd(); ::MessageBox(pMainWin->m_hWnd, pMsg, _T("Thread1 Message"), MB_OK); //_T()是一个宏, g_eventObj.Lock(); //使本线程处于等待状态 pMsg = _T("Thread1 is unlocked"); ::MessageBox(pMainWin->m_hWnd, pMsg, _T("Thread1 Message"), MB_OK); g_eventObj.Lock(); //使本线程处于等待状态 pMsg = _T("Thread1 is unlocked again"); ::MessageBox(pMainWin->m_hWnd, pMsg, _T("Thread1 Message"), MB_OK); return 0; } //子线程2 UINT MsgThread2(LPVOID pParam) { LPCWSTR pMsg = (LPCWSTR)pParam; CWnd* pMainWin = AfxGetMainWnd(); ::MessageBox(pMainWin->m_hWnd, pMsg, _T("Thread2 Message"), MB_OK); g_eventObj.Lock(); //使本线程处于等待状态 pMsg = _T("Thread2 is unlocked"); ::MessageBox(pMainWin->m_hWnd, pMsg, _T("Thread2 Message"), MB_OK); return 0; } //子线程3 UINT MsgThread3(LPVOID pParam) { g_eventObj.SetEvent(); //把事件设置为发信状态 return 0; } /************************************************************************/ /* 启动线程 按钮消息响应 */ /************************************************************************/ void CThread1Dlg::OnBnClickedButtonThead() { // TODO: 在此添加控件通知处理程序代码 AfxBeginThread( MsgThread1,_T("Thread1 is started") ); AfxBeginThread(MsgThread2, _T("Thread2 is started")); }
运行过程如下:
手动事件对象: 把定义事件对象的代码改为:
CEvent g_eventObj(FALSE,TRUE);
CCriticalSection类:
例子程序:
/************************************************************************/ /* 临界段 */ /************************************************************************/ CCriticalSection g_criticalSection; //不需要参数 /************************************************************************/ /*作为子线程 */ /************************************************************************/ UINT MsgThread(LPVOID pParam) { g_criticalSection.Lock(); LPCWSTR pMsg = (LPCWSTR)pParam; CWnd* pMainWin = AfxGetMainWnd(); ::MessageBox(pMainWin->m_hWnd, pMsg, L"Thread1 Message", MB_OK); g_criticalSection.Unlock(); return 0; } //子线程2 UINT MsgThread2(LPVOID pParam) { g_criticalSection.Lock(); LPCWSTR pMsg = (LPCWSTR)pParam; CWnd* pMainWin = AfxGetMainWnd(); ::MessageBox(pMainWin->m_hWnd, pMsg, L"Thread2 Message", MB_OK); g_criticalSection.Unlock(); return 0; } /************************************************************************/ /* 启动线程 按钮消息响应 */ /************************************************************************/ void CThread1Dlg::OnBnClickedButtonThead() { // TODO: 在此添加控件通知处理程序代码 AfxBeginThread( MsgThread,_T("Thread1 is started") ); AfxBeginThread(MsgThread2, _T("Thread2 is started")); }
线程1先获得临界段,在关闭线程1创建的消息框后,线程2才运行。
CMutex类:
CMutex(
BOOL bInitiallyOwn = FALSE, //默认互斥体状态为非锁定
LPCTSTR lpszName = NULL, //互斥体名称
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL );
CSemaphore类:
CSemaphore( LONG lInitialCount = 1, //计数器初值 LONG lMaxCount = 1, //计数上限 LPCTSTR pstrName=NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);
例子:
CSemaphore g_Smph(2,3); //计数器初值=2,上限=3 /************************************************************************/ /*作为子线程 */ /************************************************************************/ UINT MsgThread(LPVOID pParam) { g_Smph.Lock(); LPCWSTR pMsg = (LPCWSTR)pParam; CWnd* pMainWin = AfxGetMainWnd(); ::MessageBox(pMainWin->m_hWnd, pMsg, L"Thread1 Message", MB_OK); g_Smph.Unlock(); return 0; } /************************************************************************/ /* 启动线程 按钮消息响应 */ /************************************************************************/ void CThread1Dlg::OnBnClickedButtonThead() { // 可以以同一段代码多次创建不同线程 AfxBeginThread( MsgThread,_T("Thread1 is started") ); AfxBeginThread(MsgThread, _T("Thread2 is started")); AfxBeginThread(MsgThread, _T("Thread3 is started")); AfxBeginThread(MsgThread, _T("Thread4 is started")); }
运行过程: 程序先执行,进程1,2.关闭其中一个后马上执行进程3,而后执行进程4.
附注:
问:
#define ABC L"ABC"
L 宏是干什么用的,和Unicode相关吗?
如果这样,这和
#define ABC _T("ABC")
有分别吗?
答:
L表示UNICODE串,比如wchar_t* str = L"yangsongx";
_T在ANSI编译模式下表示ANSI串,在UNICODE下表示UNICODE串,比如
TCHAR* str = _T("yangsongx");
在ANSI下编译就是 char* str = "yangsongx";
在UNICODE下编译就是 wchar_t* str = L"yangsongx";
标签:style blog http color io 使用 ar strong 文件
原文地址:http://www.cnblogs.com/leoreed/p/4006923.html