-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
complex-threads.pl
executable file
·127 lines (104 loc) · 1.85 KB
/
complex-threads.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/perl
use strict;
use warnings;
use Parallel::ForkManager;
use constant PATIENCE => 50;
my %workers = ();
my %tids = ();
my %pids = ();
my $max_forks = 3;
my $total_forks = 10;
sub actually_do_something
{
my ($c) = @_;
print "Fork ID number: $c\n";
sleep 3;
}
sub my_defined
{
my ($str) = @_;
if ((!defined $str) || ($str eq ''))
{
return 0;
}
return 1;
}
sub cleanup_by_pid
{
my ($pid) = @_;
my $tid;
if (exists($pids{$pid}))
{
$tid = $pids{$pid};
}
if (defined($tid) && exists($tids{$tid}))
{
delete $tids{$tid};
}
if (exists($pids{$pid}))
{
delete $pids{$pid};
}
if (exists($workers{$pid}))
{
delete $workers{$pid};
}
print "Timed out: $tid - $pid\n";
}
sub cleanup_by_threadid
{
my ($tid) = @_;
my $pid;
if (exists($tids{$tid}))
{
$pid = $tids{$tid};
}
if (exists($tids{$tid}))
{
delete $tids{$tid};
}
if (defined($pid) && exists($pids{$pid}))
{
delete $pids{$pid};
}
if (defined($pid) && exists($workers{$pid}))
{
delete $workers{$pid};
}
print "Cleaned up: $tid - $pid\n";
}
sub dismiss_hung_workers
{
while (my ($pid, $started_at) = each %workers)
{
next unless time() - $started_at > PATIENCE;
kill TERM => $pid;
cleanup_by_pid($pid);
}
}
sub main
{
my $pm = Parallel::ForkManager->new($max_forks); # number of parallel processes
$pm->run_on_wait(\&dismiss_hung_workers, 1); # 1 second between callback invocations
$pm->run_on_finish(sub {
my ($pid, $tid) = @_;
cleanup_by_threadid($tid);
});
for my $i (1 .. $total_forks)
{
my $pid;
if ($pid = $pm->start)
{
$tids{$i} = $pid;
$pids{$pid} = $i;
$workers{$pid} = time();
next;
}
#... do some work with $data in the child process ...
actually_do_something($i);
$pm->finish($i); # Terminates the child process
cleanup_by_threadid($i);
}
$pm->wait_all_children;
}
&main;