【问题标题】:Kqueue/epoll (FreeBSD/Linux) with non-blocking socket: when can I free buffer memory after write/send/sendto?具有非阻塞套接字的 Kqueue/epoll (FreeBSD/Linux):写入/发送/发送后何时可以释放缓冲内存?
【发布时间】:2020-02-19 14:12:44
【问题描述】:

我有使用 kqueue/epoll (FreeBSD/Linux) 的非阻塞套接字(TCP 或 UPD 套接字)。当我想将字节传输到另一端时,我可以使用 write/send/sendto。它们每个都使用 char* 缓冲区进行传输,但我不明白在调用 write/send/sendto 后何时必须释放缓冲区内存。

  1. 如果 write/send/sendto 返回接受的字节数并且这个数字等于缓冲区大小,我可以立即释放缓冲区内存是否正确?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存?
  2. 如果 write/send/sendto 返回接受的字节数并且这个数字不等于缓冲区大小,我只能立即释放接受的字节,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux)事件继续传输不接受的字节和下一个字节?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存并传输下一个字节?
  3. 如果写/发送/发送返回EAGAIN(kqueue)或EAGAIN是否正确|| EWOULDBLOCK (Linux),我无法释放缓冲区内存,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来重新传输相同的字节?

【问题讨论】:

  • 您是在问操作系统在send(2) 系统调用返回后是否仍在使用您的const void *msg 缓冲区?
  • @RichardSmith 是的,带有非阻塞套接字。
  • 我很确定系统调用的第一个任务是将缓冲区从用户空间复制到内核空间,因此一旦系统调用返回,释放缓冲区总是安全的。当然,如果消息没有完全传输,你仍然需要对消息的剩余部分进行另一个系统调用。

标签: linux freebsd nonblocking epoll kqueue


【解决方案1】:

尽管您使用的是非阻塞套接字,但 write/send/sendto 调用仍然是同步的。这意味着您可以在它告诉您调用成功后立即释放缓冲区。

1。是的

当 write/send/sendto 返回完整的缓冲区大小时,表示缓冲区的全部内容已复制到套接字发送缓冲区,您可以立即释放缓冲区。

2。是的

当 write/send/sendto 返回部分大小时,您应该等待下一个可写事件发送剩余字节。

3。是的

EAGAIN 或 EWOULDBLOCK 表示写入非阻塞套接字时写入缓冲区已满。您应该再次发送这些字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-24
    • 2010-11-26
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 2012-09-15
    • 2012-03-24
    相关资源
    最近更新 更多