【问题标题】:python script to kill and start itselfpython脚本杀死并启动自己
【发布时间】:2016-03-06 19:13:56
【问题描述】:

我想在一小时内达到指定时间时启动我的 python 脚本的新实例并终止当前实例。 python 脚本使用 crontab 自动启动。无限循环读取数据。如果在 59 秒 30 和 59 秒 59 之间有数据传入,则文件将关闭,我希望脚本使用新进程 ID 启动自身的新实例并终止旧进程。目前我正在使用

  subprocess.call(['python', '/home/pi/script.py'])
  sys.exit(1)

这会启动一个新的 python 脚本实例,但当我使用 top 检查进程时,旧的仍然可见并且(似乎)处于活动状态。

有没有更好的方法让程序在 python 脚本中启动并杀死自己?

另一种方法使用由 python 脚本调用的 bash 脚本:

#!/bin/sh

PID=`ps -eaf | grep python | grep -v grep | awk '{print $2}'`
if [[ "" !=  "$PID" ]]; then
  echo "killing $PID"
  kill -9 $PID
  sleep 1
  sudo python /home/pi/readserial_V4_RP.py &
  exit 1
fi

但这行不通,因为 python 脚本在 bash 脚本杀死它之前就结束了。我可以在不杀死 python 的情况下启动 python 脚本 进程,但是在启动 python 脚本的新实例之前,如何确定没有 python 脚本正在运行。

因为我有一种感觉,当我运行多个相同的 python 脚本时,第一个启动的脚本正在做所有的“工作”,而其他的只是处于空闲状态......

【问题讨论】:

    标签: python subprocess kill restart


    【解决方案1】:

    与其让进程尝试重新启动自己,不如让一个瘦的父脚本运行真正的脚本。父监视器只是在脚本退出时重新启动脚本。由于父级一直等到子级完全退出,因此您不会运行多个版本。在完整的实现中,父进程拥有您需要的任何系统守护程序代码,而子进程则专注于任务。

    这个例子运行了一个非常无聊的程序,它会在命令行指定的秒数内休眠

    import multiprocessing
    import time
    import sys
    import os
    import traceback
    
    def the_real_work_done_here(sleep_time):
        try:
            print(os.getpid(), 'start work')
            time.sleep(sleep_time)
            print(os.getpid(), 'end work')
            exit(0)
        except Exception:
            traceback.print_exc()
            exit(2)
    
    def monitor(sleep_time):
        while 1:
            proc = multiprocessing.Process(target=the_real_work_done_here,
                args=(sleep_time,))
            proc.start()
            proc.join()
            if proc.exitcode != 0:
                print('something went wrong... terminating')
                exit(proc.exitcode)
    
    
    if __name__ == '__main__':
        try:
            sleep_time = int(sys.argv[1])
            monitor(sleep_time)
        except (KeyError, ValueError):
            print('usage: test.py sleeptime')
            exit(1)
    

    【讨论】:

    • 这看起来真的很有帮助。我明天试试,然后给答复。到目前为止,伙计们!
    【解决方案2】:

    更好的方法是使用:

      child = subprocess.Popen(['python','/home/pi/script.py'],shell=True,stdout=subprocess.PIPE)
      output,error = child.communicate()
      print output, error
      sys.exit()
    

    【讨论】:

    • 谢谢!我也用shell=True 尝试过,但结果相同。我猜 stdout 给了我一个日志,如果有错误,我可以在其中看到错误?或者它在做什么?
    • communicate() 在进程退出之前不会返回。如果您想控制该过程,请使用 poll() 并定期检查输出内容。当需要终止进程时,外部脚本可以使用 kill()。
    • @Henin RK 您的方法似乎不起作用。当前进程结束,但脚本不会再次启动。对不对,我现在这样做的方式是,python脚本的旧实例是父进程,只有在父进程结束时才能杀死子进程?我用不同的方法和一个问题将一个 bash 脚本编辑到我的问题中。
    【解决方案3】:

    我知道这是一篇旧帖子,但我需要一种方法来重新启动进程但杀死旧的。 它与 creationflags=subprocess.DETACHED_PROCESS 配合得很好。

    test.py

    from time import sleep
    import subprocess
    import sys
    
    print("Start")
    sleep(1)
    
    print("Start New")
    child = subprocess.Popen(['python','test.py'],creationflags=subprocess.DETACHED_PROCESS)
    sleep(1)
    
    sys.exit()
    

    【讨论】:

      猜你喜欢
      • 2021-10-09
      • 2022-11-12
      • 2021-05-02
      • 1970-01-01
      • 2022-10-21
      • 2016-10-08
      • 1970-01-01
      • 2018-04-10
      • 2013-03-26
      相关资源
      最近更新 更多