2016-08-22 67 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