Multithreading 多线程Perl脚本和crontab/init脚本
我对使用线程的Multithreading 多线程Perl脚本和crontab/init脚本,multithreading,perl,crontab,Multithreading,Perl,Crontab,我对使用线程的Perl脚本有问题 当我手动启动它时,它工作正常,但当我使用crontab启动它时,我有以下反馈: Perl已退出活动线程: 0 running and unjoined 1 finished and unjoined 0 running and detached crontad上的PATH变量和SHELL变量是正确的 我试图创建一个init脚本(作为服务启动),但出现了相同的错误: Feb 24 08:04:48服务器内核:perl[103293]:在4
Perl
脚本有问题
当我手动启动它时,它工作正常,但当我使用crontab启动它时,我有以下反馈:
Perl已退出活动线程:
0 running and unjoined
1 finished and unjoined
0 running and detached
crontad上的PATH
变量和SHELL
变量是正确的
我试图创建一个init脚本(作为服务启动),但出现了相同的错误:
Feb 24 08:04:48服务器内核:perl[103293]:在4a8 ip上发生故障
00007f6cfd075dd9 sp 00007fffb93437c0中出现错误4
libperl.so[7F6CFCFDFF000+183000]Feb 24 08:04:49服务器
test_ping[102238]:Perl已退出,带有活动线程:Feb 24 08:04:49
服务器测试\u ping[102238]:0正在运行且未连接2月24日08:04:49
服务器测试\u ping[102238]:1已完成且未连接2月24日08:04:49
服务器测试\u ping[102238]:0正在运行并已分离
因此,我还尝试使用以下方法修改perl:
for my $thread (threads->list) {
$thread->join();
}
而不是
for my $thread (threads->list) {
$thread->detach();
}
在我手动启动脚本时进行了修改之后,这个脚本似乎被卡住/冻结了
所以,要继续,这是我的全部支票:
}首先,不要拆下螺纹。当你这样做的时候,你不能等待他们完成
for (my $i= 0; $i < $thread_num; $i++) {
threads->create(\&process) -> detach();
}
...
for my $thread (threads->list) {
$thread->detach();
}
现在的问题是:为什么你的线程没有完成?好吧,你从来没有告诉他们退出,所以他们从来没有这样做!您需要要求他们退出,这可以通过添加以下内容来实现:
$q_queue->end();
下面是应用上述修复后得到的结果。我还将所有与线程相关的代码移出了
进程
,因为它不属于那里。最后,通过将输出代码移动到自己的线程中,我消除了对$index
的依赖
sub process {
my ($q_line) = @_;
...
return join("|", $q_index, $q_name, $q_type, $q_query, @$r_tab{qw( min med avg max dev loss err )});
}
my $request_q = Thread::Queue->new();
my $response_q = Thread::Queue->new();
my @worker_threads;
for (1..$thread_num) {
push @worker_threads, async {
while (defined( my $request = $request_q->dequeue() )) {
$response_q->enqueue( process($request) );
}
};
}
my $output_thread = do {
my $datestring = localtime();
open(my $fh, '>', $output_file)
or die("Can't create file \"$output_file\": $!\n");
async {
while (defined( my $response = $response_q->dequeue() )) {
print($fh "$datestring|$response\n");
}
}
};
{
my %protos = map { $_ => 1 } qw( icmp tcp ldap dig );
open(my $fh, '<', $data_file)
or die("Can't open file \"$data_file\": $!\n");
my $index = 0;
while (<$fh>) {
s/^\s+//;
s/\s+\z//;
next if $_ eq "" || /^#/;
my ($proto) = split /\|/;
next if !$protos{$proto};
$request_q->enqueue(++$index ."|". $_);
}
}
$request_q->end();
$_->join() for @worker_threads;
$response_q->end();
$output_threads->join();
子流程{
我的($q_线)=@;
...
返回连接(“|”)、$q_索引、$q_名称、$q_类型、$q_查询、@$r_选项卡{qw(最小平均最大开发损失错误)});
}
我的$request_q=Thread::Queue->new();
我的$response_q=Thread::Queue->new();
我的@worker_线程;
用于(1..$thread_num){
推送@worker\u线程,异步{
while(已定义(my$request=$request\u q->dequeue()){
$response_q->排队(进程($request));
}
};
}
我的$output\u thread=do{
my$datestring=localtime();
打开(我的$fh,'>',$output_文件)
或者死亡(“无法创建文件\“$output\u file\”:$!\n”);
异步的{
while(已定义(my$response=$response\u q->dequeue()){
打印($fh“$datestring |$response\n”);
}
}
};
{
我的%protos=map{$\=>1}qw(icmp-tcp-ldap-dig);
打开(我的$fh,'如果你能拿出一个最小的、可编译的代码片段来重现你所遇到的问题,那将是非常有帮助的。这就是为什么我要一个仍然重现问题的最小代码片段。因为问题可能与代码有关。我已经做了这个修改,而且更糟。脚本不会当我手动启动它时[root@SERVER]#./test_ping.sh@elbraa94,再次,你问为什么进程
没有返回,但你没有显示进程
。我只能修复你没有问到的问题。抱歉,我在我的主要帖子中添加了进程函数,所以我是对的。你从来没有告诉你的线程退出,所以这只是一个按照我详细说明的那样做的问题。哎哟我改变了很多事情。
for (1..$thread_num) {
threads->create(\&process);
}
...
... Tell the threads to finish up ...
for my $thread (threads->list) {
$thread->join();
}
$q_queue->end();
sub process {
my ($q_line) = @_;
...
return join("|", $q_index, $q_name, $q_type, $q_query, @$r_tab{qw( min med avg max dev loss err )});
}
my $request_q = Thread::Queue->new();
my $response_q = Thread::Queue->new();
my @worker_threads;
for (1..$thread_num) {
push @worker_threads, async {
while (defined( my $request = $request_q->dequeue() )) {
$response_q->enqueue( process($request) );
}
};
}
my $output_thread = do {
my $datestring = localtime();
open(my $fh, '>', $output_file)
or die("Can't create file \"$output_file\": $!\n");
async {
while (defined( my $response = $response_q->dequeue() )) {
print($fh "$datestring|$response\n");
}
}
};
{
my %protos = map { $_ => 1 } qw( icmp tcp ldap dig );
open(my $fh, '<', $data_file)
or die("Can't open file \"$data_file\": $!\n");
my $index = 0;
while (<$fh>) {
s/^\s+//;
s/\s+\z//;
next if $_ eq "" || /^#/;
my ($proto) = split /\|/;
next if !$protos{$proto};
$request_q->enqueue(++$index ."|". $_);
}
}
$request_q->end();
$_->join() for @worker_threads;
$response_q->end();
$output_threads->join();