Perl Threads Terminating Abnormally.

I've used threads before, but not with Perl.
I tried looking up these errors and using 'join' instead of 'detach' with no luck.
Here is the code I am currently using:

#!/usr/bin/perl -w

use warnings;
use threads;
use threads::shared;

$Linux='Linux';
$Greek='Greek';

      my $thr1 = threads->create(\&work1);

      sub work1 {
            open(FILE,"/home/mine/text");
              if (grep{/$Greek/} <FILE>){
                print "/home/mine/text exists!\n"
              }else{
                system("echo '' > /dev/null");
              }
          close FILE;
       $thr1->detach();
     }

     my $thr2 = threads->create(\&work2);

     sub work2 {
           $filename = "/home/mine/kcron";
             if (-e $filename) {
               print "/home/mine/kcron exists!\n";
             }else{
               system("echo '' > /dev/null");
             }
         $thr2->detach();
}
     my $thr3 = threads->create(\&work3);

     sub work3 {
           open(FILE,"/home/mine/geek.txt");
             if (grep{/$Linux/} <FILE>){
               print "/home/mine/geek.txt exists!\n";
             }else{
               system("echo '' > /dev/null");
             }
          close FILE;           
       $thr3->detach();
}

select(undef,undef,undef,.1);
exit();

These are the current errors I am getting:

# ./unixthrd.pl
/home/mine/text exists!
Thread 1 terminated abnormally: Can't call method "detach" on an undefined value at ./unixthrd.pl line 21.
/home/mine/kcron exists!
Thread 2 terminated abnormally: Can't call method "detach" on an undefined value at ./unixthrd.pl line 33.
/home/mine/geek.txt exists!
Thread 3 terminated abnormally: Can't call method "detach" on an undefined value at ./unixthrd.pl line 45.
Perl exited with active threads:
    0 running and unjoined
    3 finished and unjoined
    0 running and detached

Any advice much appreciated.

Threads die naturally when the subroutine is complete (return). Detach is for different situations, I believe.

1 Like

Finally got it!

#!/usr/bin/perl -w

use threads;
use threads::shared;

$Linux='Linux';
$Greek='Greek';

      sub work1 {
            open(FILE,"/home/ph33r/text");
              if (grep{/$Greek/} <FILE>){
                print "/home/ph33r/text exists!\n";
              }else{
                system("echo '' > /dev/null");
              }
          close FILE;
     }
     my $thr1 = threads->create(\&work1);
     $thr1->join();

     sub work2 {
           $filename = "/home/ph33r/kcron";
             if (-e $filename) {
               print "/home/ph33r/kcron exists!\n";
             }else{
               system("echo '' > /dev/null");
             }
     }
     my $thr2 = threads->create(\&work2);
     $thr2->join();


     sub work3 {
           open(FILE,"/home/ph33r/geek.txt");
             if (grep{/$Linux/} <FILE>){
               print "/home/ph33r/geek.txt exists!\n";
             }else{
               system("echo '' > /dev/null");
             }
           close FILE;
     }
     my $thr3 = threads->create(\&work3);
     $thr3->join();

With all threads joined the unwanted error finally goes away:

# ./unixthrd.pl 
/home/ph33r/text exists!
/home/ph33r/kcron exists!
/home/ph33r/geek.txt exists!

Much thanks to DGPickett for the motivation!

While there are locks like mutex, I like to use threads in a flow paradign like shell scripts, with pipes or ring buffers from one to the next. On thread can be a dispatcher, writing buffers to many threads, and another might be a collector, reading buffers from many threads. Pipes let your threads block, which is nice as threads should not consume CPU when idle, but who wants to sleep and poll (sleep short and waste CPU, sleep long and add latency)? You can poll() or select() if you have many pipes to block on. Dispatcher and collector could be the same thread, so it can add or remove threads for demand.