my $quit = 0; my %tasks = ( sub_1 => { code=>\&sub_1, state=>'idle', deps=>[ ] }, sub_2 => { code=>\&sub_2, state=>'idle', deps=>[ ] }, sub_3 => { code=>\&sub_3, state=>'idle', deps=>[ 'sub_1' ] }, sub_4 => { code=>\&sub_4, state=>'idle', deps=>[ 'sub_1' ] }, sub_5 => { code=>\&sub_5, state=>'idle', deps=>[ 'sub_2' ] }, sub_6 => { code=>\&sub_6, state=>'idle', deps=>[ 'sub_2' ] }, sub_7 => { code=>\&sub_7, state=>'idle', deps=>[ 'sub_1', 'sub_2' ] }, ); sub sleep { # No work to do, so doze for a while ... } sub get_next_task { my $task; for my $cur (keys %tasks) { next unless $tasks{$cur}{state} eq 'idle'; my $deps_not_ready = 0; for my $dep (@{$tasks{$cur}{deps}}) { if ($tasks{$dep}{state} ne 'done') { ++$deps_not_ready; } } next unless $deps_not_ready == 0; return $task; } } sub thread { while (! $quit) { my $task = get_next_task(); if (defined $task) { $tasks{$task}{state}='busy'; $tasks{$task}{started}=time; if (&{$tasks{$task}{code}}()) { $tasks{$task}{state}='done'; } else { $tasks{$task}{state}='FAULT'; } $tasks{$task}{finished}=time; } else { # No tasks are available right now sleep(); } } }