(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
SetDlgItemText(IDC_EDIT_SEND,"");
}
Lesson 16 線程同步與異步套接字
1. 事件對象
事件對象同上一課中的互斥對象一樣屬於內核對象,它包含三個成員:使用讀數,用於指明該事件是一個自動重置的還是人工重置的事件的布爾值,用於指明該事件處於已通知狀態還是未通知狀態的布爾值.
當人工重置的事件對象得到通知時,等待該事件對象的所有純種無變為可高度線程,而一個自動重置的事件對象得到通知時,等待該事件對象的線程中人有一個變為可高度線程.所以一般使用線程同步時使用自動重置.
創建事件對象:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全選項,默認為NULL
BOOL bManualReset, // reset type,TRUE(人工),FALSE(自動)
BOOL bInitialState, // initial state,TRUE(有信號狀態)
LPCTSTR lpName // object name.事件對象名
);
BOOL SetEvent(HANDLE hEvent);把指定的事件對象設置為有信號狀態◢本◢作◢品◢由◢思◢兔◢網◢提◢供◢線◢上◢閱◢讀◢
BOOL ReSetEvent(HANDLE hEvent);把指定的事件對象設置為無信號狀態
BOOL CloseHandle( HANDLE hObject ); // handle to object關閉事件對象
DWORD WaitForSingleObject(//請求內核對象,一旦得到事件對象,就進入代碼中
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // time-out interval
);
以下是一個模擬火車站售票的多線程程序(使用事件對象實現線程同步)
#include
#include
int tickets = 100;//共享的資源,火車票
HANDLE g_hEvent;//全局的事件對象句柄
//線程處理函數原型聲明
DWORD WINAPI Thread1Proc(
LPVOID lpParameter // thread data
);
DWORD WINAPI Thread2Proc(
LPVOID lpParameter // thread data
);
void main(){
// g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//創建一個人工重置的匿名事件對象,當調用SetEvent時所有的線程都可以執行,不能實現同步
// SetEvent(g_hEvent);//將事件對象設置為有信號狀態
g_hEvent = CreateEvent(NULL, FALSE, FALSE, "tickets");
//創建一個自動重置的有名事件對象,當調用SetEvent時隻有一個線程可以執行
SetEvent(g_hEvent);
//可以通過創建有名的事件對象來實現隻有一個程序實例運行
if (g_hEvent)//有值
{
if (ERROR_ALREADY_EXISTS == GetLastError())//以事件對象存在為條件實現隻有一個實例運行限製,因為事件對象是內核對象,由操作係統管理,因此可以在多個線程間訪問