Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > RE: how to run an arbitrary function with timeout?

Reply
Thread Tools

RE: how to run an arbitrary function with timeout?

 
 
Tim Peters
Guest
Posts: n/a
 
      05-14-2004
[Garry Hodgson]
> i'm building a test suite on top of unittest, and some
> of the tests involve things that might hang, like trying
> to connect to a wedged server. so i'd like a simple function
> that i can call that will run a given (func,args) pair and
> return either the value or raise an exception if it times
> out. this seems like it should be straightforward, but i've
> not had much luck getting it to work.
>
> my latest attempt, below, raises the exception ok,
> but still doesn't return until snooze() completes:


What doesn't return? The snooze() function? You told that to sleep for 10
seconds, and it does, then it prints 'waking up' and returns. Your call to
RunWithTimeout also returns, at the point it raises its exception. You
can't expect to see "ok" get printed, because when you raise TookTooLong,
RunWithTimeout's invocation ends immediately (as raising an uncaught
exception does in any function, threads or not) -- RunWithTimeout never
executes its "return 'ok'" line.

> --> xx
> going to sleep
> Traceback (most recent call last):
> File "./xx", line 26, in ?
> print RunWithTimeout( snooze, (10,), 2 )
> File "./xx", line 16, in RunWithTimeout
> raise TookTooLong, 'fsdfsdf'
> __main__.TookTooLong: fsdfsdf
>
> ...8 second delay here...
>
> waking up
>
>
> can someone tell me what i'm doing wrong?


Best I can guess, you're expecting something that can't happen, but I'm not
sure exactly what.

> #!/usr/bin/env python2.3
>
> from threading import *
> from time import sleep
>
> class TookTooLong( Exception ):
> pass
>
> def RunWithTimeout( func, args, timeout ):
> t = Thread( target=func, args=args )
> t.start()
> t.join( timeout )
>
> if t.isAlive():
> del t


That line didn't accomplish anything useful. If you expected it to "do
something", then that's the problem. All it does is unbind the local name
"t". If, for example, you expected it to kill the thread, that won't
happen.

> raise TookTooLong, 'fsdfsdf'
> return 'ok'
>
>
> def snooze( duration ):
> print 'going to sleep'
> sleep( duration )
> print 'waking up'


That function executes in its entirety when you call it, and there's nothing
you can do to stop that (Python doesn't supply any way to stop a thread T
from outside T).

>
> if __name__ == '__main__':
> print RunWithTimeout( snooze, (10,), 2 )


It would have helped a lot if you had spelled out the output you *expected*
to see. The output this actually produced is what I expected to see.


 
Reply With Quote
 
 
 
 
Garry Hodgson
Guest
Posts: n/a
 
      05-14-2004
"Tim Peters" <(E-Mail Removed)> wrote:

> Best I can guess, you're expecting something that can't happen, but I'm not
> sure exactly what.


ok, let me rephrase my question.

i would like a function RunWithTimeout( func, args, timeout )
i would like it to invoke the function func on arguments args.
if timeout seconds elapse before func(args) returns, i would
like it to raise an exception. if func(args) returns before timeout
seconds, i would like it return the result.

can anyone help?

thanks

----
Garry Hodgson, Technology Consultant, AT&T Labs

Be happy for this moment.
This moment is your life.

 
Reply With Quote
 
 
 
 
Mark Day
Guest
Posts: n/a
 
      05-14-2004
In article <(E-Mail Removed)>, Garry Hodgson
<(E-Mail Removed)> wrote:

> i would like a function RunWithTimeout( func, args, timeout )
> i would like it to invoke the function func on arguments args.
> if timeout seconds elapse before func(args) returns, i would
> like it to raise an exception. if func(args) returns before timeout
> seconds, i would like it return the result.


I'm guessing you want the exception raised after func has executed for
timeout seconds (as opposed to waiting for func to complete).

Since you can't stop func from the outside (as Tim said), I suppose you
could run func in a separate thread. From the original thread, you'd
have to wait for either timeout seconds or until func completes,
whichever comes first. If the timeout happened first, then raise the
exception (else you presumably return func's result). I'm no expert on
threading in Python, but I'll bet the Library Reference has the
information you need.

-Mark
 
Reply With Quote
 
Joseph T. Bore
Guest
Posts: n/a
 
      05-17-2004
Mark Day <(E-Mail Removed)> writes:
> In article <(E-Mail Removed)>, Garry Hodgson
> <(E-Mail Removed)> wrote:
>
>> i would like a function RunWithTimeout( func, args, timeout )
>> i would like it to invoke the function func on arguments args.
>> if timeout seconds elapse before func(args) returns, i would
>> like it to raise an exception. if func(args) returns before timeout
>> seconds, i would like it return the result.

>
> I'm guessing you want the exception raised after func has executed for
> timeout seconds (as opposed to waiting for func to complete).
>
> Since you can't stop func from the outside (as Tim said), I suppose you
> could run func in a separate thread. From the original thread, you'd
> have to wait for either timeout seconds or until func completes,
> whichever comes first. If the timeout happened first, then raise the
> exception (else you presumably return func's result). I'm no expert on
> threading in Python, but I'll bet the Library Reference has the
> information you need.


just use alarm and use a signal handler to be called after N seconds,
this is how I do it: (I've omitted the definition of the exception for
brevity)

-----------------------------------------------------------

import signal

#
# a alarm signal handler
#
def alarmHandler(signum, frame):
raise TimeExceededError, "Your command ran too long"

#
# a function that would run for too long
#
def infinite():
while 1:
pass
return

#
# set the alarm signal handler, and set the alarm to 1 second
#
signal.signal(signal.SIGALRM, alarmHandler)
signal.alarm(1)

#
# the function infinite would never return, after 1 second the signalHandler
# is called, which immediately just raises the exception.
#
try:
infinite()
except TimeExceededError:
# but after 1 second, the alarmHandler raises this
# exception
print "code must have gone crazy..."

-----------------------------------------------------------
 
Reply With Quote
 
Tony C
Guest
Posts: n/a
 
      05-18-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Joseph T. Bore) wrote in message news:<(E-Mail Removed)>...
> Mark Day <(E-Mail Removed)> writes:
> > In article <(E-Mail Removed)>, Garry Hodgson
> > <(E-Mail Removed)> wrote:

> import signal
>
> #
> # a alarm signal handler
> #
> def alarmHandler(signum, frame):
> raise TimeExceededError, "Your command ran too long"
>
> #
> # a function that would run for too long
> #
> def infinite():
> while 1:
> pass
> return
>
> #
> # set the alarm signal handler, and set the alarm to 1 second
> #
> signal.signal(signal.SIGALRM, alarmHandler)
> signal.alarm(1)


This is a very interesting solution.
However, signal.alarm() and signal.SIGALRM are not defined in my signal module
I'm using 2.3.3
 
Reply With Quote
 
Joseph T. Bore
Guest
Posts: n/a
 
      05-18-2004
(E-Mail Removed) (Tony C) writes:
>> # set the alarm signal handler, and set the alarm to 1 second
>> #
>> signal.signal(signal.SIGALRM, alarmHandler)
>> signal.alarm(1)

>
> This is a very interesting solution.
> However, signal.alarm() and signal.SIGALRM are not defined in my signal module
> I'm using 2.3.3


I'm using 2.2.1, but it's on unix/linux. It looks like the alarm
functionality is only available there. I guess there must be
something similar on windows, anyone have any ideas?

jb
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
In search of python idiom for accessing arbitrary fields at run time mshiltonj Python 2 07-08-2007 06:38 PM
arbitrary number of arguments in a function declaration rbt Python 4 01-02-2005 11:02 PM
calling an arbitrary function w/ arbitrary arguments Honestmath C++ 5 12-13-2004 06:18 AM
how to run an arbitrary function with timeout? Garry Hodgson Python 0 05-14-2004 04:11 PM



Advertisments