Skip to content

Instantly share code, notes, and snippets.

@lukmdo
Last active October 15, 2017 06:12
Show Gist options
  • Save lukmdo/5105021 to your computer and use it in GitHub Desktop.
Save lukmdo/5105021 to your computer and use it in GitHub Desktop.
intrigued by python signal capabilities [async]
"""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()
@lukmdo
Copy link
Author

lukmdo commented Mar 7, 2013

its about to make the idea clear - not clever

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment