如何在内存使用量较大的Perl守护程序中处理多个套接字?

时间:2008-12-11 11:54:09

标签: perl multithreading sockets ipc multiprocessing

我使用IO :: Socket :: INET使用Perl创建了一个客户端 - 服务器程序。我通过基于CGI的站点访问服务器。我的服务器程序将作为守护程序运行,并将接受多个同时连接。我的服务器进程占用大约100MB的内存空间(9个大型阵列,许多阵列......)。我希望这些哈希驻留在内存中并共享它们,这样我就不必为每个连接创建它们。哈希创建需要10-15秒。

每当通过套接字接受新连接时,我会分叉一个新进程来处理收到的每个连接的处理。由于父进程很大,每次我分叉时,处理器都会尝试为新的子进程分配内存,但是由于内存有限,产生一个新子进程需要很长时间,从而增加了响应时间。很多时候,即使是单个连接,它也会挂起。

父进程创建9个大哈希。对于每个孩子,我需要以只读模式引用一个或多个哈希。我不会通过孩子更新哈希。我想使用像copy-on-write这样的东西,通过它我可以与所有孩子共享整个100mb或由父母创建的全局变量?或任何其他机制,如线程。我希望服务器每秒至少得到100个请求,它应该能够并行处理所有这些请求。平均而言,孩子将在2秒内退出。

我在Windows XP上使用Cygwin只有1GB的RAM。我没有找到任何方法来克服这个问题。你能提出什么建议吗?我如何共享变量,每秒创建100个子进程并管理它们并同步它们,

感谢。

3 个答案:

答案 0 :(得分:3)

而不是分叉,还有另外两种方法来处理并发连接。您可以使用线程或轮询方法。

在每个连接的线程方法中,创建一个新线程来处理套接字的I / O.线程在创建过程的同一虚拟内存中运行,并且可以访问其所有数据。确保正确使用锁来同步数据的写访问权。

更有效的方法是通过select()使用轮询。在这种情况下,单个进程/线程处理所有套接字。这可以假设大多数工作都是I / O,等待I / O请求完成所花费的时间用于处理其他套接字。

进一步研究这两个选项,并决定哪一个最适合你。

例如参见:http://www.perlfect.com/articles/select.shtml

答案 1 :(得分:2)

如果您有那么多数据,我想知道您为什么不简单地使用数据库?

答案 2 :(得分:2)

这种架构不适合Cygwin。在真正的unix系统上分叉是很便宜的,但是在像Cygwin这样的假unix系统上它非常昂贵,因为所有数据都必须被复制(真正的unices使用copy-on-write)。使用线程会改变内存使用模式(更高的基本使用率,但每个线程的增加量更小),但可能性仍然是低效的。

我建议您使用轮询使用单进程方法,也可以使用非阻塞IO。