Created
August 8, 2012 19:18
-
-
Save jsjohnst/3297804 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(ticks = 1); | |
| class TimeoutException extends Exception {}; | |
| function signal_handler($signal) { | |
| throw new TimeoutException(); | |
| } | |
| pcntl_signal(SIGALRM, "signal_handler", true); | |
| pcntl_alarm(1); | |
| try { | |
| // simulate long executing block | |
| while(1) sleep(30); | |
| } catch(TimeoutException $e) { | |
| echo "Timeout exceeded"; | |
| } | |
| echo "done"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some more info, because this is one of the highest results on Google for
pcntl_alarm:declare(ticks = 1);tells the parser to enable the "tick" event per statement in your code.You must set this, otherwise pcntl_alarm won't get called periodically, and it'll never fire its interrupts.
pcntl_signal(SIGALRM, "signal_handler", true);sets up a signal that's triggered by SIGALRM (pcntl_alarm). When SIGALRM is triggered, the signal_handler function is called.pcntl_alarm(1);says to trigger the SIGALRM signal in 1 second. It will only alarm once.In the try/catch block, we're just sleeping for 30 seconds, in an infinite while loop. We won't ever exit until the
TimeoutExceptionis thrown.What happens, is
pcntl_alarmfires after one second, andpcntl_signalfiressignal_handler. This function throws aTimeoutException. The execution happens in the context of thewhileloop, so the exception bubbles up into the try/catch statement.The result, is after 1s the application exists.
Some fun things to note:
pcntl_alarm(1);only causes an interrupt once. You need to call it again to make subsequent interrupts occur.sleep()can be interrupted by the alarm signal. This is not true for all functions.sleep()will not resume after the alarm signal. Try replacing thethrowinsidesignal_handlerwithecho "derp"; pcntl_alarm(1);and you'll see "derp" printed every 1 second.declare(ticks = 1)provides an instruction to the php parser. It will apply to every file after you have set it. This makes the order of file inclusion important. If you don't want it to apply, you can always set it back to 0 at the end of the file you need it in.ticksis not set (before it's set, or set back to 0), ticks will not be observed because the interrupt events are not written into the opcode. The alarm will only occur after execution returns to a file that hasticksset.declare(ticks=1)set (approx 1milmd5ops in a loop).