gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 12:06:27 25 4
gpt4 key购买 nike

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

在这个 child 中,在服务器套接字上调用 accept() 不起作用。我收到一个 EAGAIN 错误(非阻塞套接字)。而在主进程中调用 accept() 效果很好。

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

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

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

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

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

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

最佳答案

其实问题并不是我一开始想的那样。以下是我为实现工作进程之间连接的一些基本负载平衡所做的工作的回顾。

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

问题是我的父进程告诉子进程接受套接字并在之后立即重新进入循环,它运行 select()再次。但是如果 child 还没有接受套接字,select()再次返回,用于相同的连接。这就是我收到 EAGAIN 错误的原因,实际上我调用了 accept()两次(或更多取决于速度进程间竞争条件)!

解决方案是等待 child 在管道上回答“嘿,我接受了连接,没关系!”,然后返回到 select()。循环。

这工作得很好。对于好奇的人,可以在此处使用 Python 中的实现:https://github.com/thibautd/Kiwi !

关于python - 为什么父进程中的 select() 会使子进程中的 accept() 不可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10142347/

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