我正在研究一些基于Apache的MPM prefork服务器的Python代码。我更像是一个应用程序员,而不是网络程序员,从我读史蒂文斯已经有10年了,所以我正在努力加快理解代码。accept()与在多个进程之间共享的套接字(基于Apache预执行)
我发现了how Apache's prefork code works, by Sander Temme的简短说明。
通常以root身份运行的父进程绑定到套接字 (通常是端口80或443)。它产生子代,继承套接字的开放 文件描述符,并将uid和gid更改为非特权用户和组。孩子们构造了监听器文件描述符(如果有多个监听器) 的轮询集 并监视其上的活动。如果找到活动,孩子在活动套接字上调用 accept()并处理连接。当它与 完成时,它返回到观看pollset(或听众文件 描述符)。
由于多个子项都处于活动状态,并且它们都继承了相同的套接字文件描述符,所以它们将观察同一个pollset。 一个接受互斥体只允许一个孩子实际观看民意调查组, ,一旦发现一个活动的套接字,它将解锁互斥体,所以 下一个孩子可以开始观看民意调查组。如果只有一个 侦听器,则不会使用接受互斥量,并且所有子级都将在 accept()中挂起。
这几乎是我看到的代码的工作方式,但我不明白一些事情。
1)“孩子”和“听众”之间有什么区别?我认为每个孩子都是一个听众,这对我所看到的代码来说是真实的,但在Temme的描述中,可以有“单一的听众”和“孩子”。孩子什么时候会有多个听众?
2)(与1相关)这是每进程互斥锁还是系统互斥锁?对于这个问题,为什么有一个互斥体?不接受(2)对所有听众都做自己的互斥吗?我的研究表明,我确实需要一个互斥体,并且互斥体必须贯穿整个系统。 (羊群,旗语等)
Temme接着说:在共享内存 区(记分牌)
儿童纪录,当他们最后 服务的请求。空闲的孩子可能会被 父母程序杀死,致 满足MaxSpareServers。如果太少, 孩子空闲,父母会 产卵孩子满足 MinSpareServers。
3)是否有一个很好的参考代码(最好在Python中)?我发现Perl的Net::Server::Prefork,它使用管道而不是共享内存作为记分板。我发现了一篇Randal Schwartz的文章,它只执行preforking,但没有记分牌。
pre-fork example from the Perl Cookbook没有任何类型的锁定选择,Chris Siebenmann's Python example表示它基于Apache,但为记分板使用配对套接字,而不是共享内存,并使用套接字控件,将给定子控件包含到'接受。这完全不符合Apache描述。
你是否使用'mod_wsgi'作为Apache和Python之间的接口?如果是这样,它应该为你处理所有这些。 – 2009-08-18 13:04:02
这是一个纯Python预执行WSGI服务器。我的客户希望为不需要Apache和mod_wsgi的地方提供轻量级解决方案,或者同等的解决方案。我找到的唯一一个只有Python的WSGI服务器是Spawning,它需要eventlet。 ......虽然现在我发现flup有一个像Siebenmann's的实现,它使用记分板的管道而不是共享内存,并且具有可接受的许可证给我的客户端。 – 2009-08-18 13:23:13