无法让 python subprocess.Popen() 在后台启动另一个 python 脚本
Can't get python subprocess.Popen() to start another python script in the background
我在这里有点困惑。我有一个 python 脚本 (gather.py),它从一个 .xml 文件中收集信息,并在休眠 60 秒的无限循环中将其上传到数据库中;顺便说一句,所有这些都是本地的。我正在使用 Flask 运行 一个稍后会从数据库中提取信息的网页,但目前它所做的只是显示一个示例页面 (main.py)。我想 运行 main.py 启动 gather.py 作为不会阻止 Flask 启动的后台进程,我尝试导入 gather.py 但它暂停了进程(无限期) 并且 Flask 不会启动。在谷歌搜索一段时间后,似乎最好的选择是使用任务队列(Celery)和消息代理(RabbitMQ)来处理这个问题。如果应用程序要在后台做很多事情,这很好,但我只需要它做 1 或 2 件事。所以我做了更多的挖掘,发现 posts 指出 subprocess.Popen()
可以完成这项工作。我尝试使用它,但我认为它没有失败,因为它没有引发任何错误,但数据库是空的。我确认 gather.py 和 main.py 都是独立工作的。我尝试 运行 在 IDLE 中使用以下代码:
subprocess.Popen([sys.executable, 'path\to\gather.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
并在 return 中得到了这个:
<subprocess.Popen object at 0x049A1CF0>
现在,我不知道这意味着什么,我尝试使用 .value
和 .attrib
,但可以理解我明白了:
AttributeError: 'Popen' object has no attribute 'value'
和
AttributeError: 'Popen' object has no attribute 'attrib'
然后我在 Whosebug post 上读到 stdout=subprocess.PIPE
会导致程序停止,所以在 'just in case' 时刻,我 运行:
subprocess.Popen([sys.executable, 'path\to\gather.py'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
并在 return 中得到了这个:
<subprocess.Popen object at 0x034A77D0>
在整个过程中,数据库表一直是空的。我是 subprocess
模块的新手,但所有这些检查,我无法弄清楚为什么它不是 运行ning gather.py。是因为它有一个无限循环吗?如果有更好的选择请告诉我。
Python版本:3.4.4
PS。 IDK 如果这很重要,但我正在 运行 在 Windows 10 PC 上安装 Python (PortableApps) 的便携式版本。这就是为什么我在 subprocess.Popen()
.
中包含 sys.executable
解决方案 1(全部在 python 脚本中):
尝试使用线程和队列。
我这样做:
from flask import Flask
from flask import request
import json
from Queue import Queue
from threading import Thread
import time
def task(q):
q.put(0)
t = time.time()
while True:
time.sleep(1)
q.put(time.time() - t)
queue = Queue()
worker = Thread(target=task, args=(queue,))
worker.start()
app = Flask(__name__)
@app.route('/')
def message_from_queue():
msg = "Running: calculate %f seconds" % queue.get()
return msg
if __name__ == '__main__':
app.run(host='0.0.0.0')
如果您 运行 此代码每次访问“/”都会在后台 task
中计算一个值。也许您需要阻塞直到任务获得值,但问题中的信息不足。当然,您需要重构 gather.py 以为其传递队列。
方案二(使用系统脚本):
对于 windows,从那里创建一个 .bat 文件和 运行 两个脚本:
@echo off
start python 'path\to\gather.py'
set FLASK_APP=app.py
flask run
这将 运行 gather.py 然后启动烧瓶服务器。如果您使用 start /min python 'path\to\gather.py'
,收集将 运行 处于最小化模式。
subprocess.Popen 无法打开 python 程序,因为它将 python 识别为文件而不是可执行文件。 Subprocess.Popen 只能打开.exe 文件,除此之外别无他法。
您可以使用:
os.system('python_file_path.py')
但它不会是后台进程(取决于您的脚本)
我在这里有点困惑。我有一个 python 脚本 (gather.py),它从一个 .xml 文件中收集信息,并在休眠 60 秒的无限循环中将其上传到数据库中;顺便说一句,所有这些都是本地的。我正在使用 Flask 运行 一个稍后会从数据库中提取信息的网页,但目前它所做的只是显示一个示例页面 (main.py)。我想 运行 main.py 启动 gather.py 作为不会阻止 Flask 启动的后台进程,我尝试导入 gather.py 但它暂停了进程(无限期) 并且 Flask 不会启动。在谷歌搜索一段时间后,似乎最好的选择是使用任务队列(Celery)和消息代理(RabbitMQ)来处理这个问题。如果应用程序要在后台做很多事情,这很好,但我只需要它做 1 或 2 件事。所以我做了更多的挖掘,发现 posts 指出 subprocess.Popen()
可以完成这项工作。我尝试使用它,但我认为它没有失败,因为它没有引发任何错误,但数据库是空的。我确认 gather.py 和 main.py 都是独立工作的。我尝试 运行 在 IDLE 中使用以下代码:
subprocess.Popen([sys.executable, 'path\to\gather.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
并在 return 中得到了这个:
<subprocess.Popen object at 0x049A1CF0>
现在,我不知道这意味着什么,我尝试使用 .value
和 .attrib
,但可以理解我明白了:
AttributeError: 'Popen' object has no attribute 'value'
和
AttributeError: 'Popen' object has no attribute 'attrib'
然后我在 Whosebug post 上读到 stdout=subprocess.PIPE
会导致程序停止,所以在 'just in case' 时刻,我 运行:
subprocess.Popen([sys.executable, 'path\to\gather.py'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
并在 return 中得到了这个:
<subprocess.Popen object at 0x034A77D0>
在整个过程中,数据库表一直是空的。我是 subprocess
模块的新手,但所有这些检查,我无法弄清楚为什么它不是 运行ning gather.py。是因为它有一个无限循环吗?如果有更好的选择请告诉我。
Python版本:3.4.4
PS。 IDK 如果这很重要,但我正在 运行 在 Windows 10 PC 上安装 Python (PortableApps) 的便携式版本。这就是为什么我在 subprocess.Popen()
.
sys.executable
解决方案 1(全部在 python 脚本中): 尝试使用线程和队列。
我这样做:
from flask import Flask
from flask import request
import json
from Queue import Queue
from threading import Thread
import time
def task(q):
q.put(0)
t = time.time()
while True:
time.sleep(1)
q.put(time.time() - t)
queue = Queue()
worker = Thread(target=task, args=(queue,))
worker.start()
app = Flask(__name__)
@app.route('/')
def message_from_queue():
msg = "Running: calculate %f seconds" % queue.get()
return msg
if __name__ == '__main__':
app.run(host='0.0.0.0')
如果您 运行 此代码每次访问“/”都会在后台 task
中计算一个值。也许您需要阻塞直到任务获得值,但问题中的信息不足。当然,您需要重构 gather.py 以为其传递队列。
方案二(使用系统脚本):
对于 windows,从那里创建一个 .bat 文件和 运行 两个脚本:
@echo off
start python 'path\to\gather.py'
set FLASK_APP=app.py
flask run
这将 运行 gather.py 然后启动烧瓶服务器。如果您使用 start /min python 'path\to\gather.py'
,收集将 运行 处于最小化模式。
subprocess.Popen 无法打开 python 程序,因为它将 python 识别为文件而不是可执行文件。 Subprocess.Popen 只能打开.exe 文件,除此之外别无他法。 您可以使用:
os.system('python_file_path.py')
但它不会是后台进程(取决于您的脚本)