事件對象:
??????事件對象也屬于內核對象,包含一個計數器,一個用于指明該事件是一個自動重置的事件還是一個人工重置的事件的布爾值,另一個用于指明該事件是處于已通知還是未通知狀態的布爾值。
兩種事件對象:
1.人工重置的事件。?? 當一個人工重置的事件得到通知時,等待該事件的所有線程均為可調度線程。
2.自動重置的事件。?? 當一個自動重置的事件得到通知時,等待該事件的線程中只有一個線程變為可調動線程。
關鍵代碼段:
關鍵代碼段(臨界區)工作在用戶方式下。
關鍵代碼段(臨界區)是指一小代碼段,在代碼能夠執行前,它必須獨占對某些資源的訪問權。
線程死鎖:
線程1擁有了臨界區對象A,等待臨界區對象B的擁有權,線程2擁有了臨界區對象B,等待臨界區對象A的擁有權,就造成了死鎖。
互斥對象、事件對象和關鍵代碼段的比較
互斥對象和事件對象都屬于內核對象,利用內核對象進行線程同步,速度較慢,但利用互斥對象和事件對象這樣的內核對象,可以在多個進程中的各個線程間進行同步。
關鍵代碼段是工作在用戶方式下,同步速度較快,但在使用關鍵代碼段時,很容易進入死鎖狀態,因為在等待進入關鍵代碼段時無法設定超時值。
推薦書目:《Windows核心編程》機械工業出版社
基于消息的異步套接字
Windows套接字在2種模式下執行I/O操作,阻塞和非阻塞。
在阻塞模式下,在I/O操作完成前,執行操作的Winsock函數會一直等待下去,不會立即返回程序(將控制權交還給程序)。
在非阻塞模式下,Winsock函數無論如何都會立即返回。
?Windows? Sockets為了支持Windows消息驅動機制,使應用程序開發者能方便的處理網絡通信,它對網絡事件采取了基于消息的異步存取策略。
Windows Sockets的異步選擇函數WSAAsyncSelect()提供了消息機制的網絡事件選擇,當使用它登記的網絡事件發生時,Windows應用程序相應窗口函數將收到一個消息,消息中指示了發生的網絡事件,以及與事件相關的一些信息。
相關函數說明
int? WSAEnumProtocols(LPINT?? lpiProtocols, LPWSAPROTOCOL_INFO? lpProtocolBuffer,? ILPDWORD? lpdwBufferLength);
Win32平臺支持多種不同的網絡協議,采用Winsock2,? 就可直接使用任何一種協議的網絡應用程序了。通過WSAEnumrotocols函數可以獲得系統中安裝的網絡協議的信息。
lpPrototocols:一個以NULL結尾的協議標示號數組,這個參數是可選的,如果lpProtocol為NULL,則返回所有可用協議的信息,否則,只返回數組中協議的信息。
lpProtocolBuffer? [out],一個用WSAPROTOCOL_INFO結構體填充的緩沖區。WSAPROTOCOL_INFO用來存放或者得到一個指定協議的完整信息。
lpdwBufferLength [in , out],在輸入時,指定傳遞給WSAEnumProtocols()函數的lpProtocolBuffer緩沖區的長度;
在輸出時,存有獲取所有請求信息需傳遞給WSAEnumrotocols()函數的最小緩沖區長度。
這個函數不能重復調用,傳入的緩沖區必須足夠大以便能存放所有的元素。
這個規定降低了該函數的復雜度,并且由于一個機器上裝載的協議數目往往是很少的,所以不會產生問題。
SOCKET?? WSASocket(int?? af,???int?? type,? int?? protocol?? ,LPWSAPROTOCOL_INFO?? lpProtpcolInfo,?? GROUP??? g,? DWORD??? dwFliags);
前3個參數和socket()函數的前3個參數含義一樣。
lpProtocolInfo,一個指向WSAPROTOCOL_INFO結構體的指針,該結構定義了所創建的套接字的特性。如果lpProtocolInfo為NULL,則套接字綁定到與指定的結構WSAPROTOCOL_INFO相關的提供者。
?g?? ,保留的。
dwFlags, 套接字屬性的描述。
int????WSARecvFrom(SOCKET???s, LPWSABUF??? lpBuffer,? DWORD? dwBufferCount? , LPDWORD?? lpNumberOfBytesRecvd,?? LPDWORD?? lpFlags,? struct? sockaddr *? lpFrom,? LPINT? lpFromLen,?? LPWSAOVERLAPPED?? lpOverLapped,? LPWSAOVERLAPPED_COMPLETION_ROUTINE??? lpCompletionRountine)
s,標示套接字的描述符。
lpBuffer[in, out]? ,一個指向WSABUF結構體的指針。每一個WSABUF結構體包含一個緩沖區的指針和緩沖區的長度。
dwBufferCount,? lpBuffer數組中WSABUF結構體的數目。
lpNumberOfBytesRecvd??? [out],? 如果接收操作立即完成,則為一個指向本次調用所接收的字節數的指針。
lpFlags[in ,out] ,一個指向標示位的指針。
lpFrom[out], 可選指針,指向重疊操作完成后存放源地址的緩沖區。
lpFrpmLen[in,? out],指向緩沖區大小的指針,僅當指定了lpFrom才需要。
lpOverlapped,一個指向WSAOVERLAPPED結構體的指針(對于非重疊套接字則忽略)。
lpCompletionRoutine,? 一個指向接收操作完成時調用的完成例程的指針(對于非重疊套接字則忽略)。
int? WSASendTo(SOCKET? s,? LPWSABUF? lpBuffer,? DWORD? dwufferCount, LPDWORD?? lpNumberOfBytesSent,? DWORD? dwFlags, const struct sockaddr FAR *?? lpTo, int?? iToLen,? LPWSAOVERLAPPED?? lpOverLapped,? LPOVERLAPPED_COMPLETION_ROUTINE? lpCompletionRoutine)
s, 標示一個套接字(可能已連接)的描述符。
lpBuffer,? 一個指向WSABUF結構體的指針。每一個WSABUF的結構體包含一個緩沖區的指針和緩沖區的長度。
dwBufferCount,? lpBuffer數組中WSABUF的數目。
lpNumberOfBytesSent? [out],? 如果發送操作立即完成,則為一個本次調用的所發送的字節數的指針。
dwFlags,? 指示影響操作行為的標示位。
lpTo,? 可選指針,指向目標套接字的地址。
iToLen,? lpTo的地址長度。
lpOverLapped,? 一個指向WSAOVERLAPPED結構的指針(對于非重疊套接字則忽略)。
lpComletionRoutine, 一個指向操作完成時調用的完成例程的指針(對于非重疊套接字則忽略)。