accept(),在多个进程之间共享套接字(基于Apache preforking)

我正在研究一些以Apache的MPM prefork服务器为模型的Python代码。我是一名应用程序员,而不是网络程序员,自从我读Stevens已经10年了,所以我正努力加快理解代码。 我找到了Sander Temme对Apache的prefork代码如何工作的简短描述。   父进程通常以root身份运行,绑定到套接字   (通常是80或443端口)。它产生了继承开放的孩子   套接字的文件描述符,并将uid和gid更改为   没有特权的用户和组。孩子们构建了一个pollset   监听器文件描述符(如果有多个监听器)   并注意它/他们的活动。如果找到活动,则孩子打电话   在活动套接字上接受()并处理连接。几时   完成后,它返回到观察pollset(或监听器文件)   描述)。      由于多个孩子都很活跃,他们都继承了同样的孩子   套接字文件描述符,他们将观看相同的pollset。   接受互斥锁只允许一个孩子实际观看轮询集,   一旦找到一个活动的套接字,它就会解锁互斥锁   下一个孩子可以开始观看民意调查。如果只有一个   监听器,不接受互斥,并且所有孩子都会挂起   接受()。 这几乎就是我所看到的代码的工作方式,但我不了解一些事情。 1)“孩子”和“听众”之间有什么区别?我认为每个孩子都是一个倾听者,这对于我正在看的代码是正确的,但在Temme的描述中,可以有“单个听众”和“孩子”。孩子什么时候会有多个听众? 2)(与1相关)这是一个进程互斥锁还是系统互斥锁?就此而言,为什么要使用互斥锁?不接受(2)在所有听众中做自己的互斥量?我的研究表明我确实需要一个互斥锁,并且互斥锁必须跨越整个系统。 (羊群,信号量等) 特梅继续说:   儿童在共享记忆中记录   区域(记分牌),当他们持续   提出要求。空闲的孩子可能会   被父进程杀死   满足MaxSpareServers。如果太少了   孩子们闲着,父母会   产卵儿童满足   比MinSpareServers。 3)这个实现是否有一个很好的参考代码(最好是在Python中)?我找到了Perl的Net :: Server :: Prefork,它为记分板使用管道而不是共享内存。我发现兰德尔施瓦茨的一篇文章只做了预备,但没有做记分牌。 来自Perl Cookbook的pre-fork示例没有任何关于select的锁定,Chris Siebenmann的Python示例说它基于Apache但是使用成对的套接字用于记分板,而不是共享内存,并使用套接字进行控制,包括控制给定的孩子'a'ccept。这根本不符合Apache描述。     
已邀请:
关于(1),监听器仅仅是对存在接受连接的套接字的引用。由于Apache可以同时接受多个套接字上的连接,例如80/443,因此有多个侦听器套接字。当时间到来时,每个子进程都需要监听所有这些套接字。由于accept()一次只能在一个套接字上完成,因此它之前是poll / select,因此可以知道哪个侦听器套接字应该执行accept。 关于(2),它是全局或跨进程的互斥体。也就是说,锁定它的一个进程将阻止尝试获取相同锁的其他进程。尽管accept()在技术上会将进程序列化,但是多个侦听器套接字的存在意味着您不能依赖它,因为您事先不知道哪个套接字要执行接受。即使在单个侦听器套接字的情况下,接受互斥的原因是如果有大量进程处理请求,那么如果操作系统唤醒所有进程以查看哪个进程然后具有accept()返回它,则可能相当昂贵。由于Apache在prefork模式下可能有100多个进程,这可能会导致问题。 因此,如果您只有一个侦听器套接字并且知道只有少数进程想要执行accept()调用,那么您可以取消跨进程接受互斥锁。     

要回复问题请先登录注册