Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

using timers to force an execution time

8 views
Skip to first unread message

superpollo

unread,
Jul 16, 2009, 6:34:20 AM7/16/09
to
hello.

based upon previuos suggestions, i tried to write a program in which i
would like to have a certain code fragment to execute only for a
specified amount of time (say 3 seconds), then bail out.

but i get the following:

$ cat tmr004.py
#!/usr/bin/python -u

import threading , time

e = threading.Event()
t = threading.Timer(3.0, e.set)
t.start()
print time.asctime(time.localtime(time.time()))
while not e.isSet():
for repeat in range(10):
print time.time()
time.sleep(0.66)
print time.asctime(time.localtime(time.time()))
$ ./tmr004.py
Thu Jul 16 12:31:27 2009
1247740287.44
1247740288.1
1247740288.76
1247740289.42
1247740290.08
1247740290.74
1247740291.4
1247740292.06
1247740292.72
1247740293.38
Thu Jul 16 12:31:34 2009
$

see? the while body ran for about 7 seconds... i bet it has to do with
the fact that the timer does not control inner loops... any suggestion?

$ python -V
Python 2.3.4
$ uname -a
Linux fisso 2.4.24 #1 Thu Feb 12 19:49:02 CET 2004 i686 GNU/Linux
$

bye

Diez B. Roggisch

unread,
Jul 16, 2009, 7:03:55 AM7/16/09
to
superpollo wrote:

Of course the inner loop isn't affected by the set event - how should it be,
if you don't check it.

if you rewrite it as this:

while True:
for repeat in range(10):
if e.isSet():
break
print time.time()
time.sleep(.66)

it should terminate earlier.

What you can't achieve in python without major black magic hackery that is
very dangerous is to terminate a thread while it is executing. Termination
has to be co-operative.

Diez

superpollo

unread,
Jul 16, 2009, 7:01:34 AM7/16/09
to
Diez B. Roggisch wrote:
> What you can't achieve in python without major black magic hackery that is
> very dangerous is to terminate a thread while it is executing. Termination
> has to be co-operative.

i see. thanks a lot.

bye

superpollo

unread,
Jul 16, 2009, 7:04:08 AM7/16/09
to
Diez B. Roggisch wrote:

> superpollo wrote:
>>see? the while body ran for about 7 seconds... i bet it has to do with
>>the fact that the timer does not control inner loops... any suggestion?
>
>
> Of course the inner loop isn't affected by the set event - how should it be,
> if you don't check it.
>
> if you rewrite it as this:
>
> while True:
> for repeat in range(10):
> if e.isSet():
> break
> print time.time()
> time.sleep(.66)
>
> it should terminate earlier.

so it seems almost impossible to allocate a certain amount of time to a
code fragment *without* somehow rewriting its logic?

am i wrong?

bye

Diez B. Roggisch

unread,
Jul 16, 2009, 7:08:40 AM7/16/09
to
Diez B. Roggisch wrote:

This is of course wrong, remove the outer "while"

Diez

Diez B. Roggisch

unread,
Jul 16, 2009, 7:11:41 AM7/16/09
to
superpollo wrote:

No, you are right, for threads that is. You can try & trick around with the
trace-functionality of python, and some ctypes-based
system-thread-module-tricks that are, as mentioned before, black-magic & a
spinning gatling gun pointed to your very own lower extremities.

The only reliable way of terminating an asynchronous computation is to use
processes, since python2.6 that's rather convenient with the
multiprocessing-module. However, that imposes some limits to what you can
do.

Diez

superpollo

unread,
Jul 16, 2009, 7:09:24 AM7/16/09
to
Diez B. Roggisch wrote:
> superpollo wrote:
>>am i wrong?
>
>
> No, you are right, for threads that is. You can try & trick around with the
> trace-functionality of python, and some ctypes-based
> system-thread-module-tricks that are, as mentioned before, black-magic & a
> spinning gatling gun pointed to your very own lower extremities.
>

OUCH.

> The only reliable way of terminating an asynchronous computation is to use
> processes, since python2.6 that's rather convenient with the
> multiprocessing-module. However, that imposes some limits to what you can
> do.

fair enough.

very helpful indeed.

bye

Nick Craig-Wood

unread,
Jul 16, 2009, 9:29:59 AM7/16/09
to

Or if you are on unix you can use signals...

It is probably just about acceptable to raise an exception in a signal
handler like this code does.

import signal, os, time

class TimeOut(Exception):
"""Thrown on alarm"""
pass

def sig_alarm(signum, frame):
raise TimeOut()

def time_out(t, fn, *args, **kwargs):
"""Calls fn with the args and kwargs returning its result or raising a TimeOut exception if it doesn't complete within t seconds"""

# Turn alarm off and read old value
old_alarm = signal.alarm(0)
# Install new handler remembering old
old_handler = signal.signal(signal.SIGALRM, sig_alarm)
# Set the timer going
signal.alarm(t)

try:
rc = fn(*args, **kwargs)
finally:
# Restore the old handler
signal.signal(signal.SIGALRM, old_handler)
signal.alarm(0)

def test():


for repeat in range(10):
print time.time()
time.sleep(0.66)

if __name__ == "__main__":
try:
time_out(3, test)
except TimeOut:
print "timed out"

--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

Paul Moore

unread,
Jul 16, 2009, 9:46:13 AM7/16/09
to Python List
2009/7/16 superpollo <us...@example.net>:

Clearly, this isn't what you are actually trying to do. For this case,
your event is getting set when you expect, but your main thread does
not check the event often enough to let it stop in a timely manner.

To fix this, remove the inner "for repeat in range(10)" loop. But I
assume that your "real" code isn't something that you can fix this
easily. If you describe your real requirement, it may be possible to
give you a better answer. (But that answer will almost certainly not
be a way of interrupting one thread from another - that's not really
possible with Python - but rather a way of achieving your goal without
*needing* to interrupt one thread from another).

Paul.

PS If you really must interrupt one thread from another, you can use C
code (or ctypes) to call the PyThreadState_SetAsyncExc API. But I'm
not going to tell you how, as it's almost certainly *not* what you
want to do in practice :-)

superpollo

unread,
Jul 16, 2009, 9:46:41 AM7/16/09
to
Nick Craig-Wood wrote:
> superpollo <us...@example.net> wrote:
> ...

> Or if you are on unix you can use signals...
>
> It is probably just about acceptable to raise an exception in a signal
> handler like this code does.
>
> ...

neat!

superpollo

unread,
Jul 16, 2009, 9:51:59 AM7/16/09
to
Nick Craig-Wood wrote:
> ...
> import signal, os, time
> ...
importing os is useless of course...
0 new messages