【问题标题】:Asynchronous I/O Linux异步 I/O Linux
【发布时间】:2012-03-17 15:45:22
【问题描述】:

需要异步 I/O 处理

计划在 Linux 上通过 aio* 调用使用异步 I/O

情况:

我已经打开了带有 AF_INET 和 SOCK_STREAM 标志的套接字 (TCP) 发送缓冲区有限制高水位线 想要异步写入那个socket,当发送缓冲区溢出时,想要断开一个socket

所以,我有问题:

  1. 当我对 TCP 套接字上的 aio_write 进行异步调用时,当 I/O 完成将到达时 - 当缓冲区写入套接字缓冲区或确认交付时?我该如何管理这种行为?

  2. 如何使用 lio_listio 技术最好地处理这个问题

问候, 安德鲁

【问题讨论】:

  • 出于兴趣,您看过 boost asio 吗?
  • 不确定 Linux。在 Windows 上,MSDN:“成功完成 WSASend 并不表示数据已成功交付”。 TBH,我对此感到惊讶 - 如果数据尚未成功交付,可能需要重新发送。如果内核、驱动程序等返回尚未确认的缓冲区,则它们必须保留数据的副本,因此失去了排队用户缓冲区的“不复制”优势:((
  • @MartinJames:它不保证成功完成使用WSASend()函数的返回值。等待适当的通知(回调、I/O 完成通知等)以获取传输的实际结果。这并不意味着您不能使用无复制,您只需要等待传输完成,然后再重新使用该特定缓冲区。
  • @AndréCaron - 好的,所以 WSASend 的完成通知(至少使用 TCP)表示成功交付?
  • @MartinJames:这表明,就操作系统的最佳知识而言,内容是按请求发送的。完成通知与调用同步send() 函数的结果基本相同。我对低级 TCP 确认以及操作系统何时确切告诉您它发送了数据不是很了解,所以我不确定这个结果是否意味着数据已成功传递(如,确认收到来自对等方)。

标签: c++ sockets tcp aio


【解决方案1】:

您希望避免在 Linux 上使用 AIO,至少目前是这样,来自aio(7)

当前的 Linux POSIX AIO 实现由 glibc 在用户空间提供。这有许多限制,最明显的是维护多个线程来执行 I/O 操作很昂贵并且扩展性很差。基于内核状态机的异步 I/O 实现的工作已经进行了一段时间(参见io_submit(2)io_setup(2)io_cancel(2)io_destroy(2)io_getevents(2)),但是这个实现还没有尚未成熟到可以使用内核系统调用完全重新实现 POSIX AIO 实现的程度。

相反,使用select(2)/poll(2)/epoll(7) 查看非阻塞 IO。

【讨论】:

  • 或者,您可以使用更高级别的框架,例如 boost::asio,它将使用最适合您系统的实现。
  • lio_listio 怎么样?提前致谢
  • 安德烈,这是假设的,但这次我需要并且想要隔离使用非常多的同时网络套接字的工作
  • 这需要更新,因为对于非缓冲文件,linux-aio 正在成功使用。还要检查最近的io_uring,它似乎通过异步编程解决了 linux 困境,并且可以与任何类型的文件(套接字、缓冲等)一起使用。
猜你喜欢
  • 2013-06-19
  • 2011-08-05
  • 2012-11-04
  • 2011-03-14
  • 1970-01-01
  • 2012-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多