为什么父进程中的select()使accept()在子进程中不可用?

2024-09-28 01:22:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个父进程,它创建2个服务器套接字并调用它们上的select()以等待新连接。当连接到达时,一条消息被发送到子进程(在创建服务器套接字之后用fork()创建,以便共享它们)。在

在此子级中,在服务器套接字上调用accept()不起作用。我得到一个EAGAIN错误(非阻塞套接字)。而在主进程中调用accept()工作得很好。在

当然,我根本不在主进程中调用accept(),我只是测试它是否有效,它确实起作用了。在

为什么我不能在父进程中的select()之后调用子进程中的accept()?在

编辑:这里的目标是创建固定数量的worker(假设8个)来处理客户端连接,就像prefork模型中那样。这些连接将是长连接,而不像HTTP。其目标是平衡工作人员之间的连接。在

为此,我使用一个共享内存变量,该变量为worker包含当前连接的客户端的数量。我想“请求”客户端数量最少的工作人员处理新连接。在

这就是为什么我在父进程中执行select(),然后向子进程发送消息,因为我想“选择”哪个进程将处理新连接。在

服务器监听多个套接字(一个用于ssl,一个没有),这就是为什么我在子进程中使用select()而不是直接使用accept(),因为我不能在我的子进程中的多个套接字上使用{}。在


Tags: 服务器消息编辑客户端目标数量进程错误
1条回答
网友
1楼 · 发布于 2024-09-28 01:22:51

事实上,问题并不是我最初想的那样。下面是我在工作进程之间的连接的一些基本负载平衡方面所做的回顾。在

  • 主进程(父进程)创建2个服务器套接字,bind()和listen()它们(例如,有和没有ssl)
  • 我用fork()创建了8个子进程,因此它们继承父进程的套接字
  • 主进程在无限循环中运行select()
  • 当它的两个套接字中有一个可用时,它通过管道向子对象发送消息。通过共享内存值来确定子进程,该值包含“子进程中”的当前客户机数量。选择当前处理最少客户机数量的进程。在
  • 然后,这个子进程调用服务器套接字上的accept()(两者之间要使用的套接字在管道中传递,因此子进程知道要在哪个套接字上调用accept()

问题是我的父进程告诉一个子进程接受套接字,然后立即重新进入循环,然后它再次运行select()。但是,如果子进程还没有接受套接字,select()会再次返回同一个连接。这就是为什么我得到了一个EAGAIN错误,事实上我调用了accept()两次(或者更多,取决于速度-进程间竞争条件)!在

解决办法是等孩子回答管道上的问题,比如“嘿,我接受了连接,没关系!”,然后返回select()循环。在

这个很好用。Python中的实现在这里提供给好奇的人:https://github.com/thibautd/Kiwi!在

相关问题 更多 >

    热门问题