Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Perl Segmentation fault

Status
Not open for further replies.

azzazzello

Technical User
Jan 25, 2005
297
US
Guys, I have a rather annoying problem. I have a threaded script that segfaults SOMETIMES. I have been able to trace the problem, but I am not sure how to remedy it. Here is the script in a nutshell. The segfault happens SOMETIMES in places where %threadcounter hash is updated, sometimes by main sometimes by threads. Does anyone have any ideas? suggestions?

Code:
use threads;
use threads::shared;
use Thread::Semaphore;
use Thread::Queue::any;

use vars qw(%threadcounter $queue $s);
share(%threadcounter);

$s = new Thread::Semaphore;
$queue = new Thread::Queue::Any;

for (1..4)
{
     my ($t1,$err1) = threads->create(\&thread_sub,$queue1);
}

while(<there are records>)
{
    $queue->enqueue([$v1,$v2,$v3]);
}

#send 4 signals to finish
for (1..4)
{ $queue->enqueue("EOF"); }

#monitor threads and clean them up when they are done
my $STILL_UPDATING = 1;
while($STILL_UPDATING)
{
   sleep(30);
   #keep looping while there are any active threads
   $STILL_UPDATING = 0;
   #when I am checking this, no thread can update the hash
   $s->down();
   foreach my $tid (keys %threadcounter)
   {
      my $active = $threadcounter{$tid};
      next if ($active == -1); #the thread is done
      if ($active)
      {
         $STILL_UPDATING = 1;
         next;
      }
      else
      {
         $DEBUG = 1;
         #clean up and delete
         my ($rv,$errstr) = threads->object($tid)->join();
         $threadcounter{$tid} = -1; #denote that thread has been joined/processed
         #return an error if any one of the threads returned null                                
         $s->up();
         die ($errstr) unless $rv;
      }
   } #end foreach (thread checker)
   $s->up();
} #end while (activity checker)
 
return 1;

sub thread_sub
{
    my $queue = shift;

    my $tid = threads->tid();
    
    $s->down; #lock
    $threadcounter[$tid] = 1; #MARK ACTIVE
    $s->up; # unlock

    while(my $data_ref = ($queue->dequeue())[0])
    {  
       if ($data_ref eq "EOF")
       { 
          flush; clean up;
 
          $s->down; #lock
          $threadcounter[$tid] = 0; #MARK INACTIVE
          $s->up; # unlock

          return (1,"ok"); 
       }
       else
       { 
          accumulate data
          at some point do some DB inserts with data; 
          if (some error) 
          {
             $s->down; #lock
             $threadcounter[$tid] = 0; #INACTIVE
             $s->up; # unlock
          
             return (0,errormsg);
          }           
       } 
   }

}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top