2016-08-22 81 views
0

所以我一直在做一些WIN32套接字編程,我想了解爲什麼重疊IO是首選。特別是,我不知道爲什麼這樣的事情爲什麼異步IO首選

if (WSARecv(
      socket, 
      dataBuf, 
      1, 
      NULL, 
      &flags, 
      &ov, 
      NULL) 
      == SOCKET_ERROR) { 
    if (WSAGetLastError() == WSA_IO_PENDING) 
    { 
     if (WSAWaitForMultipleEvents(1, &ov.hEvent, FALSE, INFINITE, FALSE) == WAIT_TIMEOUT) 
     { 
      return FALSE; 
     } 
    } else { 
     return FALSE; 
    } 
} 
// ... more code here 
return TRUE; 

優於普通IO調用這樣

recv(socket, dataBuf, bufLen), 0); 

從我的理解,在第一次調用將阻止如果IO事件沒有在WSAWaitForMultipleEvents完成,而第二個調用直接在recv上阻塞,直到數據到達。那麼稍後再調用IO調用塊的實際好處是什麼?這是否如果你有這樣做之前你可以做的事情嗎?

如果出現這種情況,那麼在數據到達之前,您所擁有的應用程序無法執行任何操作的情況下,重疊的IO是否值得?

回答

4

你表現出的情況並不是使用任何類型的異步I/O的典型原因,我想說的恰恰相反(因爲正如你所說的那樣,反正也不是真正的異步)。

使用異步I/O的典型原因僅僅是因爲它是異步的,程序可以繼續執行其他操作而不是等待I/O操作完成。

+0

你能否舉一個例子來說明等待數據時可以做的事情嗎? – FrozenHawk

+3

規範示例是一個具有多個活動套接字(例如服務器)的應用程序。您可以爲每個客戶端分配一個線程,這很簡單,但可以縮放,或者可以使用異步I/O。 –

+3

我會認爲規範應用程序是任何GUI應用程序,需要繼續響應用戶輸入和系統重畫調用,以免它變得......沒有反應。 –

1

異步I/O保存線程資源。

特別是,無論何時通過同步I/O處理某些客戶端請求,都會爲其分配一個線程。當你有1個客戶端時,它工作正常。或10個客戶。

如果你有10000個客戶端,你將不得不創建10K線程爲他們服務。這是可能的,但在許多情況下效率低下。

使用異步I/O允許在一個線程中處理大量客戶端(具體數量取決於OS /體系結構)。通常,這種方法可能會稍慢於少量客戶端的專用線程(因爲請求處理是序列化的),但在其他情況下吞吐量要好得多。

+1

這裏您確實在討論[I/O完成端口](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx)。單獨使用異步I/O不會有效地使用系統資源。 – IInspectable