【问题标题】:Why is asynchronous IO preferred为什么首选异步IO
【发布时间】:2016-12-28 11:26:06
【问题描述】:

所以我一直在做一些 WIN32 套接字编程,我试图了解为什么首选重叠 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?

【问题讨论】:

    标签: c++ sockets winapi asynchronous overlapped-io


    【解决方案1】:

    您展示的案例并不是使用任何类型异步 I/O 的典型原因,我想说的恰恰相反(因为正如您所指出的那样,它并不是真正的异步)。

    使用异步 I/O 的典型原因仅仅是因为它是异步的,您的程序可以继续执行其他操作,而不是等待 I/O 操作完成。

    【讨论】:

    • 您能举一个在等待数据时可以做的事情的例子吗?
    • 典型示例是具有多个活动套接字的应用程序,例如服务器。您可以为每个客户端设置一个线程,这很简单但扩展性很差,或者您可以使用异步 I/O。
    • 我原以为规范应用程序根本就是任何 GUI 应用程序,它需要不断响应用户输入和系统重绘调用,以免它变得……无响应。
    【解决方案2】:

    异步 ​​I/O 节省线程资源。

    特别是,每当您通过同步 I/O 处理一些客户端请求时,您都会为其分配 1 个线程。当您有 1 个客户时,它可以正常工作。或 10 个客户。

    如果您有 10000 个客户端,则必须为它们创建 10K 线程来为它们服务。这是可能的,但在许多情况下效率很低。

    使用异步 I/O 允许在一个线程中处理大量客户端(具体数量取决于操作系统/架构)。通常这种方法可能比少数客户端的专用线程慢一点(因为请求处理是序列化的),但在其他情况下吞吐量要好得多。

    【讨论】:

    • 你真的在这里谈论I/O Completion Ports。单独使用异步 I/O 不会有效地使用系统资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2017-02-04
    • 1970-01-01
    相关资源
    最近更新 更多