0

I have a multi-thread perl script using threads, works ok but when it tries to kill the hanged threads I got an error and script exists:

for (0..$threads-1) {
        $trl[$_] = threads->create(\&my_sub, $_);
        $SIG{ALRM} = sub {
                if ($trl->is_running) {
                   $trl->kill('ALRM');
                }
        }
}
for (@trl) {
        alarm 10;
        $_->join;
}

and

sub my_sub {
  $SIG{ALRM} = sub {
        threads->exit(1);
  };
  while (@site) {
  {
        lock(@site);
        $url = shift @site;
  }

and the error:

Can't call method "is_running" on an undefined value at test.pl line 61.
Perl exited with active threads:
        9 running and unjoined
        40 finished and unjoined
        0 running and detached

the line 61 is:

if ($trl->is_running) {
bsteo
  • 1,738
  • 6
  • 34
  • 60

1 Answers1

4

OK, please turn on strict and warnings. This would tell you that @trl and $trl are not the same thing. Specifically - your 'signal handler' in your main program - you're redefining every time you start a thread, and so it'll only kill the latest one. (Except it won't, because $tr1 is undefined).

I would suggest you don't want to mix signals and threads anyway though - this depends rather more on what you're doing. But usually I'd suggest - fork and kill. thread and Thread::Semaphore or Thread::Queue.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • Thanks! I will try `Thread::Semaphore`, anyway how should I correctly set the line `if ($trl->is_running) {` beside the script being not functional this way? – bsteo Aug 07 '15 at 14:16
  • I can't answer, because you can't do what you're trying to do the way you're trying to do it. I would suggest you look at using `Thread::Queue` to feed your sites through to your subs, rather than using a global array. E.g. something like in this example: http://stackoverflow.com/questions/26296206/perl-daemonize-with-child-daemons – Sobrique Aug 07 '15 at 14:25
  • Thanks! Anyway I got it, the line should be `if ($_->is_running) {` – bsteo Aug 07 '15 at 14:27
  • Yeah, but seriously - that doesn't work, because `$_` is undefined when the signal handler is called. That'll break nastily. – Sobrique Aug 07 '15 at 14:30