【发布时间】:2020-02-19 14:12:44
【问题描述】:
我有使用 kqueue/epoll (FreeBSD/Linux) 的非阻塞套接字(TCP 或 UPD 套接字)。当我想将字节传输到另一端时,我可以使用 write/send/sendto。它们每个都使用 char* 缓冲区进行传输,但我不明白在调用 write/send/sendto 后何时必须释放缓冲区内存。
- 如果 write/send/sendto 返回接受的字节数并且这个数字等于缓冲区大小,我可以立即释放缓冲区内存是否正确?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存?
- 如果 write/send/sendto 返回接受的字节数并且这个数字不等于缓冲区大小,我只能立即释放接受的字节,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux)事件继续传输不接受的字节和下一个字节?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存并传输下一个字节?
- 如果写/发送/发送返回EAGAIN(kqueue)或EAGAIN是否正确|| EWOULDBLOCK (Linux),我无法释放缓冲区内存,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来重新传输相同的字节?
【问题讨论】:
-
您是在问操作系统在
send(2)系统调用返回后是否仍在使用您的const void *msg缓冲区? -
@RichardSmith 是的,带有非阻塞套接字。
-
我很确定系统调用的第一个任务是将缓冲区从用户空间复制到内核空间,因此一旦系统调用返回,释放缓冲区总是安全的。当然,如果消息没有完全传输,你仍然需要对消息的剩余部分进行另一个系统调用。
标签: linux freebsd nonblocking epoll kqueue