【发布时间】:2012-04-25 21:46:18
【问题描述】:
我有一个父进程,它创建 2 个服务器套接字并在它们上调用 select() 以等待新连接。当连接到达时,会向子进程发送一条消息(使用fork() 创建,在服务器套接字创建之后,因此它们是共享的)。
在这个孩子中,在服务器套接字上调用 accept() 不起作用。我收到EAGAIN 错误(非阻塞套接字)。而在主进程中调用accept() 效果很好。
当然,我根本不会在主进程中调用accept(),我只是测试一下它是否有效。
为什么我不能在父进程中的 select() 之后在子进程中调用 accept()?
编辑:这里的目标是创建固定数量的工作人员(比如说 8 个)来处理客户端连接,就像在 prefork 模型中一样。这些连接将是长连接,不像 HTTP。目标是负载平衡工作人员之间的连接。
为此,我使用了一个共享内存变量,其中包含一个工作人员当前连接的客户端的数量。我想“要求”客户端数量最少的工作人员来处理新连接。
这就是为什么我在父进程中执行select(),然后向子进程发送消息,因为我想“选择”哪个进程将处理新连接。
服务器侦听多个套接字(一个用于 ssl,一个不用于),这就是为什么我在子进程中使用 select() 而不是直接使用 accept(),因为我不能在我的多个套接字上使用 accept()童工。
【问题讨论】:
-
EAGAIN 本身并不是一个真正的错误,它只是意味着调用是非阻塞的,但没有准备好连接。睡一会再试。当然,除 EAGAIN 之外的任何其他错误都是实际错误。
-
为什么不在分叉前先调用
accept?特别是因为您知道它有效。 -
我不明白你在做什么。您能否发布一些最少的代码,以便我们重现您的观察结果?
-
如果您在父进程中打开文件描述符,您可以使用Unix-domain socket magic将该描述符传递给子进程。
标签: python linux sockets process