2011-07-01 74 views
2

我对cgi web应用程序有点问题,我用ithreads做一些并行处理,其中所有的线程都有一个共同的'目标'。因此,我把它们全部分开,一旦找到我的答案,我就打电话给退出。 然而,问题在于,即使在用户关闭连接并离开后,脚本实际上仍将继续处理,当然如果问题属于资源性的话。 如果用户断开连接,有什么办法强制父进程退出?perl cgi线程

+1

你能发布代码示例? – RickF

+1

如果不知道CGI运行的环境,这是无法回答的。我猜你正在运行Apache + mod_perl并在httpd.conf中配置KeepAlive? –

回答

3

AFAIK创建和销毁线程不是(至少现在是)一个很好的Perl的做法,因为它会不断加大内存使用!
你应该用其他方式来完成工作。通常解决方案是创建一个线程池并通过共享数组或Thread::Queue发送参数。

+0

好的谢谢,但这并没有解决我的问题... –

+1

我知道它有点晚,但无论如何你是正确的,使用线程队列是正确的方式去 –

4

如果你在Apache下运行,如果客户端过早关闭连接,它发送一个SIGTERM到CGI进程。在我的简单测试中,它将脚本和线程视为默认行为。

但是,如果服务器和客户端之间存在代理,则Apache可能无法检测到关闭连接(因为从服务器到代理的连接可能保持打开状态) - 在这种情况下,你运气不好。

0

我不知道你如何如果用户已经断开检测,但是,如果他们有,你就必须使线程停止自己,因为他们显然不会自动被打死。

销毁线程是一个危险的操作,所以没有做到这一点的好办法。

的标准方法,因为据我所知,是有一个共享变量的线程定期检查,以确定他们是否应该继续工作。在退出之前将其设置为某个值,然后检查线程中的该值。

您也可以发送信号给线程来杀死它们。 The docs对此比我知道更多。

1

我个人会建议改变你的做法,并创建这些线程的客户端连接时,将保存和准PID与客户端连接的每个线程。我个人喜欢使用守护进程而不是线程,即。 PROC ::守护进程。当客户端提前断开(线程完成之前)时,将SIGTERM发送给与该客户端关联的每个进程ID。

正常退出,覆盖在停止状态的线程进程的终止子,所以像:

$SIG{TERM} = sub { $continue = 0; }; 

其中$继续将线程处理循环的状态。你仍然不得不留意代码错误,因为即使你可以尝试重写$SIG{__DIE__},die()方法通常不会尊重它,并且没有恩典即刻死亡;)(至少从我的经验来看)