gpt4 book ai didi

c++ - UDP在不同线程中发送和接收

转载 作者:IT王子 更新时间:2023-10-29 00:43:01 28 4
gpt4 key购买 nike

Linux 内核中同一套接字处理 UDP 发送和接收的独立性如何?我的用例是一个工作线程在(最多)1000 个套接字上发送 UDP 测试流量,并在另一个工作线程中接收 UDP 回复。接收器将是一个 epoll 循环,它还接收套接字错误队列上的硬件发送和接收时间戳。

澄清一下,在执行 sendmsg() 系统调用时,这是否会在接收同一个套接字的接收线程上暂时阻塞(或生成 EAGAIN/EWOULDBLOCK)? (即如果发送和接收恰好在时间上重叠)所有套接字都设置为非阻塞模式。

另一个问题是内核中锁定的粒度 - 如果我使用 sendmmsg/recvmmsg 发送和接收,该套接字的锁是针对每个 sendmmsg 锁定一次,还是针对 sendmmsg 中的每个 UDP 数据报锁定一次?

更新:我查看了 Linux 内核中 sendmmsg 的原始补丁,似乎主要的好处是避免了多次转换用户内核空间。如果进行了任何锁定,则可能是在对 __sys_sendmsg 的单独调用中完成的: https://lwn.net/Articles/441169/

最佳答案

每个系统调用都是线程独立的。因此,只要您不涉及每个进程的内核数据,两者都会独立运行而不会相互干扰。

另一个不同的事情是内核对与同一 inode 相关的系统调用所做的事情(在这种情况下,分配给您用来通信的套接字的虚拟节点)为了序列化和对文件系统进行原子调用,内核通常会做代表整个系统调用的整个系统调用(这是一个读取、写入或 ioctl 系统调用)期间的 inode 锁(即使您执行唯一的写入调用以写入数亿字节,inode 在执行期间被阻塞整个系统调用)

在 tcp-ip 堆栈中,这是在套接字级别进行的,并且在您的情况下由特定的 AF_INET 套接字类软件控制。就udp而言,发送数据包或接收不会影响需要锁定的共享资源,但您必须查看您的udp实现(或套接字级别)以查看是否完成了一些锁定以及粒度是多少.通常情况下,锁应该只在 udp 缓冲区的加载/卸载期间使用(通常 udp 中没有缓冲区,因为套接字和网卡驱动程序足以提供足够的缓冲区资源。

关于c++ - UDP在不同线程中发送和接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42275021/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com