我必须在一个Perl脚本中执行几项任务。最好不要使用fork
或thread
。
任务A:每5秒向服务器发出一次HTTP请求。无限,不应该被阻止。如果得到:
tell
任务B做某事任务B:每1分钟发出一次mysql请求,并依赖于结果,tell
任务A做POST请求
任务C:接受套接字连接,并tell
任务A或B执行某些操作。
三个并行的不定式循环过程,并将相互通信。我怎样才能做到这一点?
答案 0 :(得分:11)
这种设计没有任何意义,并且声称最好不使用线程或子进程的说法更不合理。
您有三个请求来源:
为每个请求源创建一个线程。他们的工作仅仅是监控每个请求源,以确保在检查源时对其进行检查。因此,这些线程都不应该做任何实际的工作。如果必须执行任务,则将工作委派给工作线程。他们不发布任何东西。他们不会写入数据库。
实际任务(包括发送POST和写入数据库)由一个或多个工作线程(您的选择)执行。工作线程接收来自由三个请求源填充的单个Thread :: Queue队列的请求。
所以代码看起来像:
use threads;
use Thread::Queue qw( );
use constant NUM_WORKERS => 5; # Tweak this. Can be as low as 1.
sub poll_web {
my ($request_q) = @_;
... init ...
while (1) {
...
$request_q->enqueue([post => ...]);
...
}
}
sub poll_db { ... } # Just like poll_web
sub accept_connections { ... } # Just like poll_web
sub post_handler { ... } # Receives args passed to enqueue
{
my $request_q = Thread::Queue->new();
my %job_handlers = (
post => \&post_handler,
...
);
for (1..NUM_WORKERS) {
async {
while (1) {
my $job = $request_q->dequeue();
my ($job_type, @args) = @$job;
my $handler = $job_handlers{$job_type};
or do { warn("Unknown job type $job_type"); next };
$handler->(@args);
}
};
}
async { poll_web($request_q); };
async { poll_db($request_q); };
accept_connections($request_q);
}
如果要使用进程而不是线程,请更改
use threads;
到
use forks;
但继续使用Thread :: Queue。