如何将简单Perl请求脚本转换为多线程请求脚本
将Perl单URL检查脚本改为多线程版本
要实现批量并行检查URL内容的需求,我们可以用Perl标准库中的threads和threads::shared模块改造脚本,同时处理多个URL以提升效率。以下是改造后的完整代码:
#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use threads; use threads::shared; # 定义共享数组,存储符合条件的URL my @results : shared; print "=> 开始验证 \n\n"; my @urls = ( "http://example.com", "http://example.com/index.php", "http://example.com/news.php", "http://example.com/categories.php" ); # 设置最大线程数,避免线程过多耗尽资源 my $max_threads = 5; my @threads; foreach my $url (@urls) { # 活跃线程数达上限时,等待任意线程完成 if (scalar(threads->list(threads::running)) >= $max_threads) { $_->join() foreach threads->list(threads::joinable); } # 创建线程处理当前URL my $thread = threads->create(\&check_url, $url); push @threads, $thread; } # 等待所有剩余线程执行完毕 $_->join() foreach @threads; # 输出最终结果 print "找到包含目标内容的页面:\n"; print "- $_\n" foreach @results; # 线程执行的子函数:检查单个URL内容 sub check_url { my ($url) = @_; my $ua = LWP::UserAgent->new(); $ua->timeout(10); my $response = $ua->get($url); if ($response->is_success) { if ($response->content =~ /Exist/) { # 锁定共享数组,避免多线程写入冲突 lock @results; push @results, $url; } } else { warn "请求失败 $url: " . $response->status_line . "\n"; } }
关键改造点说明:
- 线程安全共享数据:用
: shared声明@results数组,确保多线程可安全写入;写入时用lock加锁,避免数据竞争。 - 线程数量控制:通过监控活跃线程数,达到上限时等待可回收线程,防止线程爆炸。
- 独立UserAgent实例:每个线程创建专属的
LWP::UserAgent,避免多线程共用实例导致状态冲突。 - 错误处理:新增请求失败的警告输出,方便排查问题。
- 代码规范:添加
strict和warnings提升健壮性,修正原脚本语法问题。
内容的提问来源于stack exchange,提问作者Jhon Laurence
相关产品推荐
相关产品推荐

