If the module will only be used inside a thread, you can try loading the module from inside the thread entry point function using require (and import if needed):
sub thr_func
{
require Unsafe::Module
# Unsafe::Module->import(...);
....
}
If the module is needed inside the main thread, try modifying your application so that the module is loaded (again using require and ->import()) after any threads are started, and in such a way that no other threads are started afterwards。
再次,主要讨论一下第二种情况,既主要是该非thread模块放到方法中引用。下面是一个demo。
Code
use threads;
use threads::shared;
use Thread::Queue;
no warnings 'threads';
# Time out const
my $TIMEOUT : shared;
$TIMEOUT = 1;
# the sig for end thread
my $TERM : shared;
$TERM = 0;
#my $excel;
$SIG{'INT'} = $SIG{'TERM'} = sub{ print("\n>>> Terminating <<<\n"); $TERM=1;};
$SIG{'KILL'} = sub{ printf("%3d <- Killed\n", threads->tid());
threads->detach() if !threads->is_detached();
threads->exit(); };
sub ThreadWatcher
{
my $queue = shift;
my %timers;
while(!$TERM)
{
#print "ThreadWatcher -- TERM : $TERM\n";
while(my $tid = $queue->dequeue_nb())
{
if (! defined($timers{$tid}{'timeout'} = $queue->dequeue()) ||
! defined($timers{$tid}{'thread'} = threads->object($tid)))
{
# No timeout - unregister thread
delete($timers{$tid});
}
}
foreach my $tid (keys(%timers))
{
#print "$timers{$tid}{'thread'} \n";
if(--$timers{$tid}{'timeout'} < 0)
{
print "thread $timers{$tid}{'thread'} will be killed.\n";
$timers{$tid}{'thread'}->kill('KILL');
delete($timers{$tid});
}
}
# tick tock
sleep(1);
}
}
sub Worker
{
#eval {use Win32::OLE::Variant;};
my ($queue, $dataqueue) = @_;
# get the thread id and register with watch
my $tid = threads->tid();
printf("Working -> %3d\n", $tid);
$queue->enqueue($tid, $TIMEOUT);
print "Worker -- TERM : $TERM\n";
while(!$TERM)
{
#my $App = $dataqueue->dequeue();
my $data = $dataqueue->dequeue();
#deal with the data
#print "Worker -- DATA : $App\n";
print "Worker -- DATA : $data\n";
#my $var = Win32::OLE::Variant->new(VT_BSTR, $data);
#print "Worker VAR: $var\n";
}
# Remove signal handler
$SIG{'KILL'} = sub {};
# Unregister with timer thread
$queue->enqueue($tid, undef);
# Tell user we're done
printf("%3d <- Finished\n", $tid);
threads->detach() if ! threads->is_detached();
threads->exit();
}
# create time thread
my $watchQueue = Thread::Queue->new();
threads->create('ThreadWatcher', $watchQueue)->detach();
# create work thread
my $dataQueue = Thread::Queue->new();
threads->create('Worker', $watchQueue, $dataQueue);
NoneSafeModelScript('C:\Joe_Chen\Perl_Projects\Threads\update.xlsx');
WairLongTime(10);