在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)
答案 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”