foreach $j (@j) { print "Next Loop $j \n"; eval { local $SIG{ALRM} = sub { die "Alarm\n"; }; alarm(2); &callfc(); }; # ^ This is much better, you localize $SIG{ALRM} inside eval, and you are also using # the new-line character in the message (and that's why it works (partially)) # In here, you should have called alarm(0) to cancel the alarm. # It doesn't matter if you are out of the eval block, the alarm continues to run # and you eventually can have an uncatched "timeout" while being on a different # part of your flow. You must call alarm(0) after your eval block (not from inside # because it can die for a different cause too and never get to the alarm(0) line). # So, I added it here: alarm 0; if ($@) { die unless $@ eq "Alarm\n"; # ^ You should send the error to the die too so you know what went wrong, # like this: die $@ unless $@ eq "Alarm\n"; # But yes, you would catch a timeout here (if alarm 0 was present too above). } else { print "Didnt\n"; } } print "I am continuing with the code\n"; # ^ Yeah... except if you didn't set alarm(0) above, and your script continues # to run and take longer than the alarm to complete, you'll eventually have an # error stating "Terminating on signal SIGALRM(14)" and wonder why that happened.