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

Re: how to set timeout for os.popen

1,301 views
Skip to first unread message

MRAB

unread,
Apr 15, 2018, 2:14:48 PM4/15/18
to
On 2018-04-15 12:01, Ho Yeung Lee wrote:
> while 1:
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
>
>
> after running over 1 hour, it stop and not return in one of tracert
>
> how to set timeout and know that this is timeout?
>
Try using the 'subprocess' module instead.

Jason Friedman

unread,
Apr 15, 2018, 4:40:21 PM4/15/18
to
>
> while 1:
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
>
>
> after running over 1 hour, it stop and not return in one of tracert
>
> how to set timeout and know that this is timeout?
>

There are a number of answers on Stackoverflow, for example
https://stackoverflow.com/questions/492519/timeout-on-a-function-call. The
first few answers there seem to be Nix-specific, with OS-agnostic
multiprocessing answers below.

Jugurtha Hadjar

unread,
Apr 16, 2018, 9:34:18 AM4/16/18
to
On 04/15/2018 12:01 PM, Ho Yeung Lee wrote:
> while 1:
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
> runner = os.popen("tracert -d www.hello.com")
> o=runner.read()
> print(o)
> runner.close()
>
>
> after running over 1 hour, it stop and not return in one of tracert
>
> how to set timeout and know that this is timeout?

import signal
import time
from contextlib import contextmanager

@contextmanager
def timeout(duration, handler):
    """Timeout after `duration` seconds."""
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(duration)
    try:
        yield
    finally:
        signal.alarm(0)


def interrupt_handler(signum, frame):
    print('Interrupt handler saves the day')
    raise TimeoutError


# You can use that in many ways:

# At definition time:

@timeout(10, interrupt_handler)
def foo():
    print('Begin foo')
    while True:
        print('foo is printing')
        time.sleep(3)


# At use time, define foo normally:

def bar():
    print('Begin bar')
    while True:
        print('bar is printing')
        time.sleep(3)
with timeout(10, interrupt_handler):
    print('I am inside with, above bar')
    bar()

eryk sun

unread,
Apr 16, 2018, 5:09:35 PM4/16/18
to
On Mon, Apr 16, 2018 at 1:33 PM, Jugurtha Hadjar
<jugurth...@gmail.com> wrote:
> On 04/15/2018 12:01 PM, Ho Yeung Lee wrote:
>>
>> while 1:
>> runner = os.popen("tracert -d www.hello.com")
>> o=runner.read()
>>
>> how to set timeout and know that this is timeout?
>
> @contextmanager
> def timeout(duration, handler):
> """Timeout after `duration` seconds."""
> signal.signal(signal.SIGALRM, handler)
> signal.alarm(duration)
> try:
> yield
> finally:
> signal.alarm(0)

The OP is most likely using Windows, which has tracert.exe instead of
traceroute.

Windows doesn't implement POSIX signals. The C runtime emulates the
ones required by standard C. This includes SIGSEGV, SIGFPE, SIGILL
based on OS exceptions; SIGINT (Ctrl+C) and SIGBREAK (Ctrl+Break) for
console applications; and SIGABRT and SIGTERM for use in-process via C
raise() and abort().

There's no alarm function to interrupt a thread that's waiting on
synchronous I/O. You could implement something similar using another
thread that calls CancelSynchronousIo(). Altertable waits can also be
interrupted, but code has to be designed with this in mind.

That said, the OP can simply switch to using
subprocess.check_output(command_line, timeout=TIMEOUT). subprocess
supports a timeout on Windows by joining a worker thread that reads
from stdout.
0 new messages