Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

using timers to force an execution time

 

 

Python python RSS feed   Index | Next | Previous | View Threaded


user at example

Jul 16, 2009, 3:34 AM

Post #1 of 12 (477 views)
Permalink
using timers to force an execution time

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
--
http://mail.python.org/mailman/listinfo/python-list


contact at xavierho

Jul 16, 2009, 3:49 AM

Post #2 of 12 (471 views)
Permalink
Re: using timers to force an execution time [In reply to]

On Thu, Jul 16, 2009 at 6:34 PM, superpollo <user [at] example> wrote:

> 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.
>
> <snip>


> 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?
>
>
I'm guessing it has to do with a sleep of 0.66 seconds x 10 times = sleep
for 6.6 seconds, and then it checks for e.isSet().

Best regards,

Ching-Yun "Xavier" Ho, Technical Artist

Contact Information
Mobile: (+61) 04 3335 4748
Skype ID: SpaXe85
Email: contact [at] xavierho
Website: http://xavierho.com/


user at example

Jul 16, 2009, 4:01 AM

Post #3 of 12 (465 views)
Permalink
Re: using timers to force an execution time [In reply 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
--
http://mail.python.org/mailman/listinfo/python-list


deets at nospam

Jul 16, 2009, 4:03 AM

Post #4 of 12 (472 views)
Permalink
Re: using timers to force an execution time [In reply to]

superpollo wrote:

> 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?

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
--
http://mail.python.org/mailman/listinfo/python-list


user at example

Jul 16, 2009, 4:04 AM

Post #5 of 12 (465 views)
Permalink
Re: using timers to force an execution time [In reply 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
--
http://mail.python.org/mailman/listinfo/python-list


deets at nospam

Jul 16, 2009, 4:08 AM

Post #6 of 12 (463 views)
Permalink
Re: using timers to force an execution time [In reply to]

Diez B. Roggisch wrote:

> superpollo wrote:
>
>> 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?
>
> 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.

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

Diez
--
http://mail.python.org/mailman/listinfo/python-list


user at example

Jul 16, 2009, 4:09 AM

Post #7 of 12 (474 views)
Permalink
Re: using timers to force an execution time [In reply 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
--
http://mail.python.org/mailman/listinfo/python-list


deets at nospam

Jul 16, 2009, 4:11 AM

Post #8 of 12 (465 views)
Permalink
Re: using timers to force an execution time [In reply to]

superpollo wrote:

> 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?

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

--
http://mail.python.org/mailman/listinfo/python-list


nick at craig-wood

Jul 16, 2009, 6:29 AM

Post #9 of 12 (459 views)
Permalink
Re: using timers to force an execution time [In reply to]

superpollo <user [at] example> wrote:
> 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.

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 <nick [at] craig-wood> -- http://www.craig-wood.com/nick
--
http://mail.python.org/mailman/listinfo/python-list


p.f.moore at gmail

Jul 16, 2009, 6:46 AM

Post #10 of 12 (454 views)
Permalink
Re: using timers to force an execution time [In reply to]

2009/7/16 superpollo <user [at] example>:
> 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?

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 :-)
--
http://mail.python.org/mailman/listinfo/python-list


user at example

Jul 16, 2009, 6:46 AM

Post #11 of 12 (454 views)
Permalink
Re: using timers to force an execution time [In reply to]

Nick Craig-Wood wrote:
> superpollo <user [at] example> 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!
--
http://mail.python.org/mailman/listinfo/python-list


user at example

Jul 16, 2009, 6:51 AM

Post #12 of 12 (449 views)
Permalink
Re: using timers to force an execution time [In reply to]

Nick Craig-Wood wrote:
> ...
> import signal, os, time
> ...
importing os is useless of course...
--
http://mail.python.org/mailman/listinfo/python-list

Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.