azzazzello
Technical User
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);
}
}
}
}