我使用cmsg激活Linux套接字tx上的时间戳。

ssize_t sendWithOptions
(int sd, std::vector<uint8_t> &payload, uint32_t destIP, int flags)
{
    msghdr msg { };
    .... // filling standard
    std::array<uint8_t, CMSG_LEN(sizeof(__u32))> buf;
    msg.msg_control = buf.data();
    msg.msg_controlen = buf.size();

    auto cmsg { CMSG_FIRSTHDR ( &msg ) };
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SO_TIMESTAMPING;
    cmsg->cmsg_len = buf.size();

    *(reinterpret_cast<__u32>(CMSG_DATA (cmsg)) = static_cast<__u32>(flags);
    return sendmsg ( sd, &msg, MSG_DONTWAIT );
}

离开函数后,“buf”会自动销毁,但是sendmsg是否需要此缓冲区才能生存更长的时间?
我是否保证一旦函数返回了发送的字节数,该函数就不需要此缓冲区。

最佳答案

除了特定的接口(interface)外,通常情况下,操作系统调用在完成后并不依赖用户空间来维护影响其操作的数据结构。异常(exception)情况将在手册页中详细说明。

特别是使用sendmsg,您可以依靠该调用立即完成-无论成功与否。因此,可以在执行操作时使用动态分配的缓冲区,并在调用后立即销毁它。

作为一个异常(exception)的示例,aio_write(2)专门用于允许用户空间将将异步完成的写操作排队。对于此调用,在成功写入数据之前,不会消耗数据。因此,在确认完成之前,您不得修改调用中提供的数据结构。该警告在手册页的NOTES部分中进行了标注:



总结:检查系统调用的手册页。但是大多数时候,您无需担心。

10-08 19:32