python轮询并在另一个Popen完成后开始

时间:2019-01-25 01:40:40

标签: python subprocess

在python中,我使用带回调的轮询通知,因此当在存储桶中检测到文件时,然后从python脚本中运行外壳程序脚本,该脚本会在1-10分钟长的任意时间运行一系列python命令。

我希望该Shell脚本在再次运行该Shell脚本之前完全完成,但是轮询通知尝试检测到新文件。我希望他们等到完成为止。

def run_shell_script(summary_message):
    cmd = './process_job.sh' + ' ' + summary_message + ' &'
    p = subprocess.Popen([cmd], shell=True)
    (output, err) = p.communicate()  
    p_status = p.wait()

def poll_notifications(project, subscription_name):
    """Polls a Cloud Pub/Sub subscription for new GCS events for display."""
    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
    project, subscription_name)

def callback(message):
    summary_message = summarize(message)
    run_shell_script(summary_message)

    subscriber.subscribe(subscription_path, callback=callback)
    print('Listening for messages on {}'.format(subscription_path))
    while True:
        time.sleep(60)

1 个答案:

答案 0 :(得分:0)

问题可能是您的子进程创建了子进程来执行“ .sh”命令。解决此问题的一种方法是让所有子进程也等待。例如,

import psutil

def run_shell_script(summary_message):
    cmd = './process_mlbox_job.sh' + ' ' + summary_message + ' &'
    p = subprocess.Popen([cmd], shell=True)
    parent = psutil.Process(p.pid)
    [child.wait() for child in parent.children(recursive=True)]
    (output, err) = p.communicate()  
    # wait_to_finish(p)
    p_status = p.wait()

#def wait_to_finish(p):
#    parent = psutil.Process(p.pid)
#    children = parent.children()
#    for child in children:
#        wait_to_finish(child)
#        child.wait()
#    p.wait()

但是,如果p进程死得太快,这可能会导致竞争。


如果这不是问题,那么还有另一种方法来管理run_shell_script进程和回调进程。您可以使用全局列表跟踪活动的子流程,并且仅在该列表为空时才启动新的子流程。例如,

messages_to_run = []
active_processes = []

def run_shell_script():
    if not messages_to_run: # indicating no messages to run
        return
    if active_processes:
        if active_processes[0].poll() is None: # indicating last process is still running
            return 
        active_process.pop(0)
    summary_message = messages_to_run.pop(0)
    cmd = './process_mlbox_job.sh' + ' ' + summary_message + ' &'
    p = subprocess.Popen([cmd], shell=True)
    active_processes.append(p)
    (output, err) = p.communicate()  
    p_status = p.wait()

另外,您需要一个无限循环,不断调用“ run_shell_script”并将任何新消息附加到“ messages_to_run”