我正在使用 libev 编写 tcp 服务器。 我在 listen() 之后创建套接字和 fork ,然后在监听套接字上启动 libev 读取观察器并在观察器回调中接收客户端连接。 可能是这样的情况: child 和 parent (如果有多个 child ,则为两个 child )收到监听套接字变得可读的事件,并且都将尝试 accept() 客户端连接,在这种情况下,其中一个进程将阻塞? 我编写了测试程序,似乎只有一个进程接收到就绪事件,但也许我错了?在这种情况下,我在哪里可以阅读有关系统行为的信息?内核如何在进程之间进行负载平衡并决定谁将接收事件?它是后端(select、epoll 等...)和/或操作系统特定的吗?
最佳答案
很有可能两个进程都从套接字接收到就绪指示,并且都将因此调用 accept()
。这就是为什么您应该始终将非阻塞文件描述符与基于事件的 API(例如 socket()
、poll()
、epoll()
)一起使用的原因之一>,或 kqueue()
(或 libev,它为其中的一个或多个提供了抽象)。如果您使用非阻塞套接字,那么一个 child 将从 accept()
获得成功的结果,而所有其他 child 将获得 EAGAIN
,忽略它,然后继续 sleep 造成伤害。
关于sockets - 在 child 中接收事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14108933/