我的 cgi Web 应用程序遇到了一些问题,我使用 ithreads 进行一些并行处理,其中所有线程都有一个共同的“目标”。因此,我将它们全部分离,一旦找到答案,我就退出。 然而问题是,即使用户关闭连接并离开,脚本实际上仍会继续处理,这当然是资源方面的问题。 如果用户断开连接,有没有办法强制退出父进程?
如果您在 Apache 下运行,如果客户端过早关闭连接,它会向 cgi 进程发送 SIGTERM。 在我的简单测试中,这会作为默认行为杀死脚本和线程。
但是,如果服务器和客户端之间存在代理,则 Apache 可能无法检测到关闭的连接(因为从服务器到代理的连接可能保持打开状态) - 在这种情况下,您运气不好。
据我所知,创建和销毁线程不是(至少现在)一个好的 Perl 实践,因为它会不断增加内存使用量!
你应该以其他方式思考来完成工作。通常解决方案是创建一个线程池并借助共享数组或 Thread::Queue.
我个人建议改变你的方法,在为客户端连接创建这些线程时,保存每个线程的 PID 并将其与客户端连接关联起来。我个人喜欢使用守护进程而不是线程,即。过程::守护进程。当客户端过早断开连接时(在线程完成之前),将 SIGTERM 发送到与该客户端关联的每个进程 ID。
要正常退出,请使用停止条件覆盖线程进程中的终止子,例如:
$SIG{TERM} = sub { $continue = 0; };
其中 $continue 是线程处理循环的条件。你仍然需要注意代码错误,因为即使你可以尝试覆盖
$SIG{__DIE__}
,die() 方法通常不会尊重这一点,并且会立即死掉而不优雅;)(至少从我的经验来看)
我不确定你如何检测用户是否已断开连接,但是,如果他们已经断开连接,你必须让线程自己停止,因为它们显然不会被自动杀死。
销毁线程是一个危险的操作,所以没有好的方法来做到这一点。
据我所知,标准方法是使用一个共享变量,线程定期检查该变量以确定它们是否应该继续工作。在退出之前将其设置为某个值,并在线程内检查该值。您还可以向线程发送信号来杀死它们。