Multithreading 如何在mod_perl上使用线程/多线程

Multithreading 如何在mod_perl上使用线程/多线程,multithreading,perl,mod-perl,mod-perl2,Multithreading,Perl,Mod Perl,Mod Perl2,下面的代码在mod_cgi上运行良好,但在mod_perl上运行不好。代码在创建第一个线程时崩溃。关于如何在mod_perl上实现线程有什么想法吗?真的有可能吗?我错过了什么 use strict; use warnings; use threads; print "Content-type: text/html\n\n"; sub testthread{ my $value = shift; print "<br>test - $value" } my @thre

下面的代码在mod_cgi上运行良好,但在mod_perl上运行不好。代码在创建第一个线程时崩溃。关于如何在mod_perl上实现线程有什么想法吗?真的有可能吗?我错过了什么

use strict;
use warnings;
use threads;

print "Content-type: text/html\n\n";

sub testthread{
   my $value = shift;
   print "<br>test - $value"
}

my @threads = ();
push(@threads, threads->new(\&testthread, 1));
push(@threads, threads->new(\&testthread, 2));
foreach (@threads) {
   $_->join;
}

exit;
使用严格;
使用警告;
使用线程;
打印“内容类型:text/html\n\n”;
子测试线程{
我的$value=shift;
打印“
测试-$value” } 我的@threads=(); 推送(@threads,threads->new(\&testthread,1)); 推送(@threads,threads->new(\&testthread,2)); foreach(@threads){ $加入; } 出口
没有给出错误消息。我的网页/脚本刚刚停止,并将此错误告知浏览器: www.abcd.com页面不工作 www.abcd.com未发送任何数据。 奇怪的是,如果我通过命令行执行脚本,它就可以正常工作

那么线程真的不能与mod_perl一起工作吗

我还没有调查线程是否与
mod_perl2
一起工作。请记住,
mod_perl
的要点是在Apache进程中运行一组持久的perl解释器

还要记住,Apache可能会杀死需要很长时间才能响应的CGI脚本。现在,再加上一组线程,您的CGI脚本随时都可能死亡,并在Apache中的某个持久Perl进程中管理这些线程,我希望很容易理解为什么人们的第一反应是“好主意!”这对于我在CGI编程中遇到的任何问题都不会成为解决方案

您能做什么或不能做什么在很大程度上取决于您选择的MPM以及您使用的
httpd
perl
是如何编译的等等

你需要解释为什么你认为你需要线程。您试图解决的问题是什么?在中使用线程将如何帮助您解决问题

见:

线程支持 为了适应Apache 2.0线程体系结构(用于线程化MPM),mod_perl 2.0需要使用线程安全的perl解释器,也称为“
ithreads
”(解释器线程)。这种机制可以在编译时启用,并确保每个Perl解释器使用其私有的
PerlInterpreter
结构来存储其符号表、堆栈和其他Perl运行时机制。当采用这种分离时,同一进程中的任意数量的线程都可以安全地执行对Perl的并发回调。当然,这要求每个线程都有自己的
PerlInterpreter
对象,或者至少每个实例在任何给定时间都只能由一个线程访问

第一个
mod_perl
生成只有一个PerlInterpreter,它由父进程构造,然后通过fork继承到子进程
mod_perl
2.0有一个可配置的
PerlInterpreter
s和两类解释器,即parent和clone。父级类似于
mod_perl
1.0,其中在启动时创建的主解释器编译任何预加载的perl代码。使用Perl API函数从父级创建克隆。在请求时,父解释器仅用于生成更多克隆,因为克隆是实际处理请求的解释器。Perl注意只复制可变数据,这意味着不需要运行时锁定,并且从父级共享诸如语法树之类的只读数据,这将减少总体
mod_Perl
内存占用

默认情况下,mod_perl创建一个解释器池,而不是为每个线程创建一个
PerlInterpreter
。池机制有助于大大减少内存使用。如前所述,语法树在所有克隆的解释器之间共享。如果您的服务器提供的请求多于
mod_perl
请求,那么
PerlInterpreter
s的数量少于线程数量将明显减少内存使用。最后,也可能是最大的胜利是内存重用:当对Perl子例程进行调用时,当变量第一次使用时,会为它们进行内存分配。变量的后续使用可能会分配更多内存,例如,如果标量变量需要保存比以前更长的字符串,或者数组中添加了新元素。作为一种优化,Perl依赖于这些分配,即使它们的值“超出范围”。mod_perl 2.0可以更好地控制传入请求使用的
perlinterpreter
。口译员存储在两个链接列表中,一个用于可用口译员,另一个用于忙口译员。当需要处理一个请求时,从可用列表的头上取一个口译员,完成后放回同一列表的头上。这意味着,例如,如果您有10个解释器配置为在启动时克隆,但并发使用的解释器不超过5个,那么这5个解释器将继续重用Perl的分配,而其他5个解释器则会小得多,但可以在需要时随时使用

可以使用配置池的各种属性

解释器池机制已抽象为一个称为“tipool”的API,即线程项池。此池可用于管理任何数据结构,如果您希望其中的线程数小于已配置的线程数,则可以使用该池。例如,基于tipool的Apache::DBI的替换将允许在同一进程的多个线程之间重用数据库连接

线程环境问题 虽然
mod_perl
本身是线程安全的,但您的代码的线程安全性可能存在问题。有关更多信息,请参阅

另一个问题是“全局”变量对于创建它们的解释器来说是全局的。可以在同一进程中运行的多个线程之间共享变量。有关详细信息,请参阅:


你想完成什么?我建议尝试多线程CGI脚本类型的东西需要som