概述
使用事件对象是实现线程同步的最简单的方法。当线程访问某一资源前,需要等待某一事件发生时,可使用事件对象进行同步。一个事件对象有两种状态:信号态与非信号态。
创建事件
创建事件的语句如下:
CEvent pEvent;
事件被创建后就自动处于非信号态,要使用它处于信号态,必须使用对件对象的成员函数SetEvent(),即:
pEvent.SetEvent();
当遇到pEvent.Lock() 时,如果pEvent 为非信号态,则将在此阻塞,一直等到有 .SetEvent();操作后才执行下去。所以当 .Lock() 放在程序前,.SetEvent() 放在程序后就能保证一个事件访问完成后其它程序才能访问. 在.h文件中创建一数据结构:
struct ThreadInfo{
CEdit *pEdit;
CButton *pCheck;
};
工作者线程
再定义两个工作者线程
UINT MyThread1( LPVOID lpParam )
{
ThreadInfo *pInfo = (ThreadInfo *) lpParam;
char buffer[MAX_PATH];
CString s;
if ( pInfo->pCheck->GetCheck() ) /* 检测是否设定事件同步 */
{
pEvent.Lock(); /* 设定为有信号 */
}
for ( int i = 0; i < 10; i++ )
{
pInfo->pEdit->GetWindowText( buffer, MAX_PATH );
s.Format( “ % s % d ”, buffer, i );
pInfo->pEdit->SetWindowText( s );
Sleep( 100 );
}
if ( pInfo->pCheck->GetCheck() )
{
pEvent.SetEvent();
}
return(0);
}
UINT MyThread2( LPVOID lpParam )
{
int i;
ThreadInfo *pInfo = (ThreadInfo *) lpParam;
char buffer[MAX_PATH];
CString s;
if ( pInfo->pCheck->GetCheck() )
{
pEvent.Lock();
}
for ( i = 0; i < 10; i++ )
{
::SendMessage( pInfo->pEdit->GetSafeHwnd(), WM_GETTEXT, MAX_PATH, (LPARAM) buffer );
s.Format( “ % d ”, i );
strcat( buffer, s );
::SendMessage( pInfo->pEdit->GetSafeHwnd(), WM_SETTEXT, 0, (LPARAM) buffer );
Sleep( 100 );
}
if ( pInfo->pCheck->GetCheck() )
{
pEvent.SetEvent();
}
return(0);
}
启动线程
void CThread_EventDlg::OnButton1()
{
// TODO: Add your control notification handler code here
Info.pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
Info.pCheck = (CButton *)GetDlgItem(IDC_CHECK1);
AfxBeginThread(MyThread1, &Info);
AfxBeginThread(MyThread2, &Info);
}