简体   繁体   English

如何同时运行多个无限循环的Python脚本

[英]How to run multiple infinitely looping Python scripts simultaneously

I have a python project which consist of 3 Python scripts that have run indefinitely, and I would like to run them simultaneously. 我有一个python项目,包含3个无限运行的Python脚本,我想同时运行它们。 They are: 他们是:

  • web.py: Is a Flask application which will be running forever as the control panel of the project. web.py:Flask应用程序将永远作为项目的控制面板运行。
  • pir.py: Is a script that whatchess the motion sensor to go HIGH, does some stuff, and then keeps looping till the sensor goes HIGH again. pir.py:脚本能够使运动传感器变为高电平,做一些事情,然后继续循环,直到传感器再次变为高电平。
  • keypadd.py: Is in a loop till the keypad goes HIGH, reads passcode combinations, does some stuff and loops again. keypadd.py:循环直到键盘变为高电平,读取密码组合,再做一些东西和循环。

I tried to run those three files with sh in a shell script. 我尝试在shell脚本中使用sh运行这三个文件。 But once the web.py runs, it seems like the other Python files are waiting in a queue untill web.py finish the job and then are going to be executed. 但是一旦web.py运行,似乎其他Python文件在队列中等待,直到web.py完成作业然后将被执行。 But the web.py will never finish the job, because it keeps looping. 但是web.py永远不会完成这项工作,因为它会不断循环。 I would like the scripts to be executed in this order: web.py, pir.py and then keypadd.py. 我希望脚本按以下顺序执行:web.py,pir.py,然后是keypadd.py。

How can I do that? 我怎样才能做到这一点?

Shell script I used: 我使用的Shell脚本:

#!/bin/sh
# launcher.sh


cd /home/pi/Ptoject
sudo python web.py
sudo python pir.py
sudo python keypadd.py

Another options would be to use a Python wrapper script instead of a shell script, import the functions you need, and run them in other processes: 另一个选择是使用Python包装器脚本而不是shell脚本,导入所需的功能,并在其他进程中运行它们:

import time
import mutliprocessing

import web
import pir
import keypadd

processes = []

for func in [web.function, pir.function, keypadd.function]:
    processes.append(multiprocessing.Process(target=func, args=(arg1, arg2)))
    processes[-1].start()

# Do stuff

while True:
    time.sleep(600) # sleep for 10 minutes
    living_processes = [p.is_alive() for p in processes]
    if living_processes < 3:
        for p in living_processes:
            p.terminate()

        print("Oops: Some processes died")
        # do other error handling here if necessary

There are some nice things about this approach: 这种方法有一些好处:

  • It is all in Python, which I think is nice when the rest of my project is Python. 这一切都在Python中,我认为当我的项目的其余部分是Python时,这是很好的。
  • You can also add some logic in the "do stuff" area that monitors your processes and kills the others if one fails with an exception, something similar to what I've done in the example. 您还可以在“do stuff”区域中添加一些逻辑来监视您的进程,如果一个异常失败则会杀死其他逻辑,类似于我在示例中所做的操作。
  • Better yet, you could create a multiprocessing.Queue() and if one process fails, send a "poison pill" to the rest to have them exit cleanly instead of terminating them. 更好的是,您可以创建一个multiprocessing.Queue() ,如果一个进程失败,向其余进程发送一个“毒丸”,让它们干净地退出而不是终止它们。 You'll need to add some logic to the infinitely looping routines to make them check the queue every once in a while to see if they should exit, and join them nicely after you've dropped the pill. 你需要在无限循环的例程中添加一些逻辑,让它们每隔一段时间检查一次队列,看看它们是否应该退出,并在你丢弃药丸后很好地加入它们。
  • Stopping everything with this approach is easier than stopping background processes. 使用这种方法停止一切比停止后台进程更容易。 A single Ctrl-C in the main script will cause a KeyboardInterrupt to be propagated to the child processes, bringing everything to a halt at the same time. 主脚本中的单个Ctrl-C将导致KeyboardInterrupt传播到子进程,同时使所有内容停止。
#!/bin/sh
# launcher.sh
cd /home/pi/Ptoject
sudo python web.py & sudo python pir.py & sudo python keypadd.py

Another solution is use supervisord and daemonize your files. 另一个解决方案是使用supervisord并守护你的文件。

Add an ampersand to fork the process- 添加&符号来分叉流程 -

cd /home/pi/Ptoject
sudo python web.py &
sudo python pir.py &
sudo python keypadd.py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM