如何在 Perl 中处理具有依赖关系的调度线程?

Dav*_*d B 2 perl multithreading

我有以下场景:

sub_1 can run immediately
sub_2 can run immediately
sub_3 can run only after sub_1 finishes
sub_4 can run only after sub_1 finishes
sub_5 can run only after sub_2 finishes
sub_6 can run only after sub_2 finishes
sub_7 can run only after both sub_1 and sub_2 finish
sub_8 can run only after both sub_1 and sub_2 finish
Run Code Online (Sandbox Code Playgroud)

我希望每个子程序尽快开始运行,而不是等待所有子程序完成。

我非常感谢您帮助为这个简单的场景创建一个干净的解决方案——我是多线程的新手。

我不确定它是否有所不同,但这些潜艇都在一个对象中。

pil*_*row 5

我建议采用“老板/工人”模型,其中一个线程管理要在工作线程中执行的子例程,工作线程在完成后将其状态报告给老板。

在这个模型中,boss 是唯一需要知道如何安排任务的线程。它可能看起来像这样:

use threads;
use Thread::Queue;
use Thread::Pool;

our $done_queue = Thread::Queue->new;
our $work_pool  = Thread::Pool->new;

sub sub_1 {
  ... do the work ...
  $done_queue->enqueue('sub_1'); # tell the boss we're all done
}

sub sub_2 {
  ... do the work ...
  $done_queue->enqueue('sub_2'); # tell boss we're done
}

...

# Main loop (boss thread)

$work_pool->enqueue(\&sub_1);
$work_pool->enqueue(\&sub_2);

while (my $sub_name = $done_queue->dequeue) {
  # You, the boss thread, keep track of state and
  # transitions however you like.  You know what's
  # just finished and what's finished in the past
  ...
}
Run Code Online (Sandbox Code Playgroud)

当然,抽象可以使这更简洁——您可以将 Pool 和 Queue 隐藏在一个对象后面,一个根本不需要sub_1()知道状态队列的对象:

$boss->enqueue( 'sub_1' => \&sub_1 ); # Will return 'sub_1' via await_completed()
$boss->enqueue( 'sub_2' => \&sub_2 ); # Will return 'sub_1'

while (my $sub_name = $boss->await_completed) {
  ...
}
Run Code Online (Sandbox Code Playgroud)