vishi has asked for the wisdom of the Perl Monks concerning the following question:
Hi Monks,
I am testing a small program to understand how interrupt handling works in a program that uses threads and the "expect.pm" module. With this code, I am calling a shell script (which basically just sleeps for X seconds - to simulate some other actual program I intend to use my Perl code for).
Lets assume my code does a bit of critical stuff and a bunch of other non critical stuff. When I get a Ctrl C while the critical stuff is running, I want the program to wait until it completes processing and then quit. Also, when it gets a Ctrl C while doing the non critical stuff, it can go ahead and abort right away (of course after performing cleanup and other housekeeping stuff)
Here's my code that does this work:
#!/usr/bin/perl use strict; #use warnings; use Term::ReadKey; use Text::Wrap; use Term::Prompt; use Expect; use threads; use threads::shared; use Term::ANSIColor; use File::Path; use HTML::Entities; use MIME::QuotedPrint; use MIME::Base64; use MIME::Lite; use Date::Calc qw(Delta_DHMS); my $pass = "<password>"; my $User = "<username>"; $SIG{'INT' } = 'interrupt'; $SIG{'QUIT'} = 'interrupt'; $SIG{'HUP' } = 'interrupt'; $SIG{'TRAP'} = 'interrupt'; $SIG{'ABRT'} = 'interrupt'; $SIG{'STOP'} = 'interrupt'; my $sshAuth = Expect->spawn("ssh $User\@hostname"); $sshAuth->log_stdout(0); my $thr1 = threads->create('thread1',$sshAuth); $thr1->join(); sub thread1 { my $sshAuth = shift; our $sleepFlag = ''; $sshAuth->expect(1000, [qr/[Yy]es/ => sub {$sshAuth->send(" +yes\n");}], [qr/[Pp]assword\:\s/ => sub {$sshAuth->send("$pass +\n");}] ); $sshAuth->log_stdout(0); $sshAuth->expect(1000, [qr/\$/ => sub {$sshAuth->send("\n");}]) +; $sshAuth->log_stdout(0); $sshAuth->expect(1000, [qr/\$/ => sub {$sshAuth->send("cd Perl\ +/Test\n");}]); $sshAuth->log_stdout(0); ###### Here are the critical tasks that should not abort on Ctrl+C + ######### our $sleepFlag = "true"; $sshAuth->expect(1000, [qr/\$/ => sub {$sshAuth->send("\.\/slee +per\.sh\n");}]); $sshAuth->log_stdout(0); print "Entering Critical sleeping ... \n"; $sshAuth->expect(1000, [qr/\$[\s]*/ => sub {$sshAuth->send( +"\n");}]); $sshAuth->log_stdout(0); print "Woke up \n"; our $sleepFlag = "false"; ###### I really dont mind if the stuff here terminates on Ctrl+C # +######## $sshAuth->expect(1000, [qr/\$/ => sub {$sshAuth->send("\.\/slee +per\.sh\n");}]); $sshAuth->log_stdout(0); print "Entering Non Critical sleeping ... \n"; $sshAuth->expect(1000, [qr/\$[\s]*/ => sub {$sshAuth->send("\n" +);}]); $sshAuth->log_stdout(0); print "Woke up \n"; $sshAuth->close(); } sub interrupt { our $sleepFlag:shared; print "$sleepFlag\n"; print "Waiting for critical tasks to finish before terminating pro +gram"; while ($sleepFlag eq "true") { print "."; sleep(3); } print "\n\nNo critical tasks are running... it\'s safe to terminat +e now...\n"; print "Terminating Program!!!\n"; }
By the way, the sleeper.sh script, that is used to simulate a task that my script runs contains this:
sleep 60 ;
When I press Ctrl C while this code is running, nothing happens. As per my understanding, while in the critical execution phase, a Ctrl C should give me the message
Waiting for critical tasks to finish before terminating programand while I press Ctrl C when the code is running in the non critical execution phase, it should print
No critical tasks are running... it's safe to terminate now... Terminating Program!!!
But as I see, nothing happens until the thread completes execution and is joined in the main thread. What am I doing wrong here?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Interrupt Handling - What am I doing wrong?
by ikegami (Patriarch) on Apr 20, 2011 at 07:44 UTC | |
by vishi (Beadle) on Apr 20, 2011 at 09:33 UTC | |
by ikegami (Patriarch) on Apr 20, 2011 at 18:05 UTC | |
by vishi (Beadle) on Apr 26, 2011 at 05:56 UTC | |
by ikegami (Patriarch) on Apr 26, 2011 at 06:57 UTC | |
|
Re: Interrupt Handling - What am I doing wrong?
by ikegami (Patriarch) on Apr 20, 2011 at 18:10 UTC |