Используя модуль 'подобрабатывают' с тайм-аутом

Вы можете использовать гибкое обновление в приложении, как описано здесь:

https://developer.android.com/guide/app-bundle/in-app-updates#immediate_flow

302
задан 4 revs, 2 users 92% 31 October 2015 в 14:18
поделиться

3 ответа

Если вы используете Unix,

import signal
  ...
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
80
ответ дан 23 November 2019 в 01:25
поделиться

Я успешно использовал killableprocess в Windows, Linux и Mac. Если вы используете Cygwin Python, вам понадобится версия killableprocess OSAF, потому что в противном случае собственные процессы Windows не будут убиты.

1
ответ дан 23 November 2019 в 01:25
поделиться

Вот решение Алекса Мартелли как модуль с правильным уничтожением процессов. Другие подходы не работают, потому что они не используют proc.communicate (). Поэтому, если у вас есть процесс, который производит много вывода, он заполнит свой выходной буфер, а затем заблокируется, пока вы что-нибудь из него не прочитаете.

from os import kill
from signal import alarm, signal, SIGALRM, SIGKILL
from subprocess import PIPE, Popen

def run(args, cwd = None, shell = False, kill_tree = True, timeout = -1, env = None):
    '''
    Run a command with a timeout after which it will be forcibly
    killed.
    '''
    class Alarm(Exception):
        pass
    def alarm_handler(signum, frame):
        raise Alarm
    p = Popen(args, shell = shell, cwd = cwd, stdout = PIPE, stderr = PIPE, env = env)
    if timeout != -1:
        signal(SIGALRM, alarm_handler)
        alarm(timeout)
    try:
        stdout, stderr = p.communicate()
        if timeout != -1:
            alarm(0)
    except Alarm:
        pids = [p.pid]
        if kill_tree:
            pids.extend(get_process_children(p.pid))
        for pid in pids:
            # process might have died before getting to this line
            # so wrap to avoid OSError: no such process
            try: 
                kill(pid, SIGKILL)
            except OSError:
                pass
        return -9, '', ''
    return p.returncode, stdout, stderr

def get_process_children(pid):
    p = Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True,
              stdout = PIPE, stderr = PIPE)
    stdout, stderr = p.communicate()
    return [int(p) for p in stdout.split()]

if __name__ == '__main__':
    print run('find /', shell = True, timeout = 3)
    print run('find', shell = True)
43
ответ дан 23 November 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: