python 解决os.popen 超时问题

Python 使用函数 os.popen 会出现过长时间等待导致阻塞问题。

python 解决os.popen 超时问题

解决方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def TIMEOUT_COMMAND(command, timeout):
    """call shell-command and either return its output or kill it
    if it doesn't normally exit within timeout seconds and return None"""
    import subprocess, datetime, os, time, signal
    cmd = command.split(" ")
    start = datetime.datetime.now()
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    while process.poll() is None:
        time.sleep(0.2)
        now = datetime.datetime.now()
        if (now - start).seconds> timeout:
            os.kill(process.pid, signal.SIGKILL)
            os.waitpid(-1, os.WNOHANG)
            return None
    return process.stdout.readlines()

循环

忙等 子进程结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import subprocess
import os
import time
tt = '555'
cmd = "python /home/100003/python/mypython/sub2.py "+" 333"+" 444 "+tt
print time.time()
sub2 = subprocess.Popen(cmd, shell=True)
while 1:
    ret1 = subprocess.Popen.poll(sub2)
    if ret1 == 0:
        print sub2.pid,'end'
        break
    elif ret1 is None:
        print  'running'
        time.sleep(1)
    else:
        print sub2.pid,'term'
        break
print time.time()

子进程结束

立即返回 使用select模块 同时可设置子进程的超时时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import subprocess
import select
import time
import signal
import os

tt = '555'
cmd = "python /home/100003/python/mypython/sub2.py "+" 333"+" 444 "+tt
timeout = 3
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell = True)
print time.time()
while 1:
    while_begin = time.time()
    print 'timeout',timeout
    fs = select.select([pro.stdout], [], [], timeout)
    if pro.stdout in fs[0]:
        tmp = pro.stdout.read()
        print 'read', tmp
        if not tmp:
            print 'end'
            print time.time()
            break
    else:
        print 'outoftime'
        print os.kill(pro.pid, signal.SIGKILL),
        break
    timeout = timeout - (time.time() - while_begin)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import subprocess, threading

class Command(object):
    def __init__(self, cmd):
        self.cmd = cmd
        self.process = None

    def run(self, timeout):
        def target():
            print 'Thread started'
            self.process = subprocess.Popen(self.cmd, shell=True)
            self.process.communicate()
            print 'Thread finished'

        thread = threading.Thread(target=target)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            print 'Terminating process'
            self.process.terminate()
            thread.join()
        print self.process.returncode

command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=3)
command.run(timeout=1)

1
2
3
4
5
6
7
8
9
10
Thread started
Process started
Process finished
Thread finished
0
Thread started
Process started
Terminating process
Thread finished
-15

如果数unix 系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import signal

proc = subprocess.Popen(
    cmd,
    stderr=subprocess.STDOUT,  # merge stdout and stderr
    stdout=subprocess.PIPE,
    shell=True)

  ...
class Alarm(Exception):
    pass

def alarm_handler(signum, frame):
    raise Alarm

signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(5*60)  # 5 minutes
try:
    stdoutdata, stderrdata = proc.communicate()
    signal.alarm(0)  # reset the alarm
except Alarm:
    print "Oops, taking too long!"
    # whatever else

本文网址: https://pylist.com/topic/104.html 转摘请注明来源

Suggested Topics

Python List 按键高效排序方法

Python含有许多古老的排序规则,这些规则在你创建定制的排序方法时会占用很多时间,而这些排序方法运行时也会拖延程序实际的运行速度。...

给ssdb python 接口提速

SSDB 是个新兴的数据库,其数据库的特点简单,性能高效,有好多python 接口,个人比较后选择一个最理想的,但还有提速空间,这里仅作经验分享。...

python SQLite 数据库提速经验

SQLite 特点是轻巧,依赖少,数据库就一个文件,打包即可提走。最近做一个应用,千万条数据,更新频繁,但处理方式很简单,首先直接用SQLite 处理,结果两分钟可以完成处理一次,这个还是太慢了。下面介绍 SQLite 优化提速的经验。...

在SAE Python上开启gzip的方法

开启 gzip 的作用自不必说,可以省很多流出带宽,可以省很多云豆。昨天这个博客的云豆消耗,其中流出带宽就占九成多,开启后就会只占五成多。...

python 对中文链接安全转码

当一个链接里包含中文时,有些浏览器并不能正确解析,这就需要首先对中文作安全转码,这里介绍用 python 对中文链接安全转码,...

python 标准库读写CSV 文件

CSV 是(Comma Separated Values 逗号分隔值)的英文缩写,通常都是纯文本文件。这里介绍使用python 标准库读写csv 文件的方法。...

Leave a Comment