Last active
October 15, 2017 06:12
-
-
Save lukmdo/5105021 to your computer and use it in GitHub Desktop.
intrigued by python signal capabilities [async]
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
"""Got intriged with signal capabilities (http://docs.python.org/2/library/signal.html) | |
I define simple ``asyncall`` function thats takes numner seconds and deffered function (similar window.setTimeout(n_ms, func/code_literal)) | |
>>> asyncall(5, lambda *args: say('A')) | |
>>> asyncall(10, lambda *args: say('B')) | |
>>> asyncall(2, lambda *args: say('C')) | |
C | |
A | |
B | |
Then only a liitle more complex: | |
async_clock = lambda i: asyncall(i, lambda *args: xtime()) | |
>>> async_clock(2) | |
Thu Mar 7 02:03:26 2013 # after 2sec | |
>>> map(async_clock, [1, 2, 3, 4, 5]) | |
[None, None, None, None, None] | |
Thu Mar 7 02:03:28 2013 | |
Thu Mar 7 02:03:29 2013 | |
Thu Mar 7 02:03:30 2013 | |
Thu Mar 7 02:03:31 2013 | |
Thu Mar 7 02:03:32 2013 | |
That is only an experiment of aving async calls without forking/threads. | |
It lacks: | |
- non-unix support | |
- ms resolution | |
- sys.getrecursionlimit() as its how its mimics the stack | |
- it has only apporx sec accuracy | |
- kill acync task ``clearTimeout`` | |
So DONT use it! More likely you will like to use: | |
- quees speeking like celery (http://www.celeryproject.org/) | |
- http://docs.python.org/2/library/threading.html#timer-objects | |
""" | |
import sys, signal, time | |
import math | |
def asyncall(nsec_later, handler): | |
prev_handler_eta = int(math.ceil(signal.getitimer(signal.ITIMER_REAL)[0])) | |
if prev_handler_eta: | |
prev_handler = signal.getsignal(signal.SIGALRM) | |
# reshedule and mimic stack, see sys.getrecursionlimit() | |
delta = prev_handler_eta - nsec_later | |
resheduled_for = min(prev_handler_eta, nsec_later) | |
if delta == 0: | |
new_handler = lambda *args: prev_handler(*args) or handler(*args) | |
elif delta < 0: | |
new_handler = lambda *args: prev_handler(*args) or asyncall(abs(delta), handler) | |
else: | |
new_handler = lambda *args: handler(*args) or asyncall(abs(delta), prev_handler) | |
signal.signal(signal.SIGALRM, new_handler) | |
signal.alarm(resheduled_for) | |
else: | |
signal.signal(signal.SIGALRM, handler) | |
signal.alarm(nsec_later) | |
def say(x): | |
print x | |
sys.stdout.flush() | |
def xtime(): | |
print time.ctime() | |
sys.stdout.flush() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
its about to make the idea clear - not clever