I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2009-02-26 20:18:54-08 by cfa4matt
CGI with threads throws error
So I've been trying to get threads working in a CGI script I'm writing. The gist of it is I'm making concurrent requests that have a time limit. If any of the requests takes too long I kill them and just use the data from the threads that finished. The issue is on a Windows box using IIS. The CGI will complete then IIS throws a 'The remote procedure call failed and did not execute' error. Every other call to the script will succeed but the odd one will fail with that error. I would try fork, alert or LWP's timeout feature but the requests are over https and there are well known and documented issues with these other methods on Windows. I'm using ActiveState Perl 5.8.8, threads 1.71 and XP sp2 w/various updates. Below is a minimal script that will reproduce the error. Any insight would be appreciated. Thanks.
#!/c/Perl/bin/perl use strict; use warnings; use threads; $|=1; local $SIG{'KILL'} = sub { threads->detach() if not threads->is_detached(); threads->exit(); }; sub main { hook(); print "Done with first call\n"; hook(); print "Done with second call\n"; } sub hook { my $hooks = [ { name => 'one', call => \&func1 }, { name => 'two', call => \&func2 }, { name => 'three', call => \&func3 }, ]; my $timelimit = 4; my ($call, $module, $addon, @threads); foreach my $i ( 0 .. $#{@$hooks} ) { my $name = $hooks->[$i]{'name'}; my $call = $hooks->[$i]{'call'}; eval { push @threads, { call => $name, func => threads->create({ 'exit' => 'thread_only' }, sub { $call->() }), }; }; print $@ if $@; } my %out; my $now = time; while( scalar keys %out != scalar @threads ) { foreach my $i ( 0 .. $#threads ) { next if defined $out{$i}; if( ref $threads[$i]->{'func'} eq 'threads' ) { next unless $threads[$i]->{'func'}->is_joinable; $out{$i} = $threads[$i]->{'func'}->join; } else { $out{$i} = $threads[$i]->{'func'}; } $out{$i} = (ref $threads[$i]->{'func'} eq 'threads' ? '[thread ' : '[') . $threads[$i]->{'call'} . ' '. (time - $now) .' sec]'. $out{$i} .'[/'. $threads[$i]->{'call'} .']'; } last if (time - $now) > $timelimit; select(undef, undef, undef, 0.5); # Alarm-friendly sleep for one half second } kill_loose_threads() if threads->tid == 0; print (join '', @out{sort keys %out}); print "\nTotal time: " . (time - $now) . "\n"; } sub kill_loose_threads { foreach my $thread ( threads->list ) { $thread->kill('KILL')->detach; } } sub func1 { sleep 1; return "I slept 1 second"; } sub func2 { sleep 3; return "I slept 3 seconds"; } sub func3 { sleep 8; return "I slept 8 seconds"; } main();
Direct Responses: 10091 | Write a response