如何根据特定条件终止以 subprocess.Popen() 开头的脚本
How to terminate the script started with subprocess.Popen() based on specific condition
我正在从名为 main.py
的主脚本启动一个名为 test.py
的 Python 脚本。
在 test.py
中,我正在跟踪一些机器学习指标。当这些指标达到某个阈值时,我想终止启动 test.py
的子流程。
如果我通过以下方式启动此脚本,是否有可能在 Python 中实现此目的:
proc = subprocess.Popen("python test.py", shell=True)
我在文档中没有找到任何可以让我自己触发此事件的内容。
已更新
执行此操作的最简单方法是将终止条件作为参数传递给 test.py
.
否则,您可以使用 stdout
和 stdin
的打印和读取。如果您想保留输出并仍然使用 Popen,请参见下文。例如,考虑一个简单的 test.py
计算(以非常低效的方式)一些素数:
test.py
import time
primes = [2, 3]
if __name__ == "__main__":
for p in primes:
print(p, flush=True)
i = 5
while True:
for p in primes:
if i % p == 0:
break
if i % p:
primes.append(i)
print(i, flush=True)
i += 2
time.sleep(.005)
您可以阅读输出并选择在达到所需输出时终止进程。例如,我想获得最大为 1000
.
的素数
import subprocess
proc = subprocess.Popen("python test.py",
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
bufsize=1, universal_newlines=True,
shell=True, text=True)
must_stop = False
primes = []
while proc.poll() is None:
line = proc.stdout.readline()
if line:
new_prime = int(line)
primes.append(new_prime)
if new_prime > 1000:
print("Threshold achieved", line)
proc.terminate()
else:
print("new prime:", new_prime)
print(primes)
请注意,由于处理和通信存在延迟,您可能会比预期多获得一两个素数。如果你想避免这种情况,你需要双向通信并且 test.py
会更复杂。如果你想在屏幕上看到 test.py
的输出,你可以打印它然后以某种方式解析它并检查是否满足条件。其他选项包括使用 os.mkfifo
(仅限 Linux,不是很困难),它提供了两个进程之间的简单通信路径:
os.mkinfo
版本
test.py
import time
import sys
primes = [2, 3]
if __name__ == "__main__":
outfile = sys.stdout
if len(sys.argv) > 1:
try:
outfile = open(sys.argv[1], "w")
except:
print("Could not open file")
for p in primes:
print(p, file=outfile, flush=True)
i = 5
while True:
for p in primes:
if i % p == 0:
break
if i % p:
primes.append(i)
print("This will be printed to screen:", i, flush=True)
print(i, file=outfile, flush=True) # this will go to the main process
i += 2
time.sleep(.005)
主文件
import subprocess
import os
import tempfile
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'fifo') # Temporary filename
os.mkfifo(filename) # Create FIFO
proc = subprocess.Popen(["python3", "test.py", filename], shell=False)
with open(filename, 'rt', 1) as fifo:
primes = []
while proc.poll() is None:
line = fifo.readline()
if line:
new_prime = int(line)
primes.append(new_prime)
if new_prime > 1000:
print("Threshold achieved", line)
proc.terminate()
else:
print("new prime:", new_prime)
print(primes)
pass
os.remove(filename)
os.rmdir(tmpdir)
我正在从名为 main.py
的主脚本启动一个名为 test.py
的 Python 脚本。
在 test.py
中,我正在跟踪一些机器学习指标。当这些指标达到某个阈值时,我想终止启动 test.py
的子流程。
如果我通过以下方式启动此脚本,是否有可能在 Python 中实现此目的:
proc = subprocess.Popen("python test.py", shell=True)
我在文档中没有找到任何可以让我自己触发此事件的内容。
已更新
执行此操作的最简单方法是将终止条件作为参数传递给 test.py
.
否则,您可以使用 stdout
和 stdin
的打印和读取。如果您想保留输出并仍然使用 Popen,请参见下文。例如,考虑一个简单的 test.py
计算(以非常低效的方式)一些素数:
test.py
import time
primes = [2, 3]
if __name__ == "__main__":
for p in primes:
print(p, flush=True)
i = 5
while True:
for p in primes:
if i % p == 0:
break
if i % p:
primes.append(i)
print(i, flush=True)
i += 2
time.sleep(.005)
您可以阅读输出并选择在达到所需输出时终止进程。例如,我想获得最大为 1000
.
import subprocess
proc = subprocess.Popen("python test.py",
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
bufsize=1, universal_newlines=True,
shell=True, text=True)
must_stop = False
primes = []
while proc.poll() is None:
line = proc.stdout.readline()
if line:
new_prime = int(line)
primes.append(new_prime)
if new_prime > 1000:
print("Threshold achieved", line)
proc.terminate()
else:
print("new prime:", new_prime)
print(primes)
请注意,由于处理和通信存在延迟,您可能会比预期多获得一两个素数。如果你想避免这种情况,你需要双向通信并且 test.py
会更复杂。如果你想在屏幕上看到 test.py
的输出,你可以打印它然后以某种方式解析它并检查是否满足条件。其他选项包括使用 os.mkfifo
(仅限 Linux,不是很困难),它提供了两个进程之间的简单通信路径:
os.mkinfo
版本
test.py
import time
import sys
primes = [2, 3]
if __name__ == "__main__":
outfile = sys.stdout
if len(sys.argv) > 1:
try:
outfile = open(sys.argv[1], "w")
except:
print("Could not open file")
for p in primes:
print(p, file=outfile, flush=True)
i = 5
while True:
for p in primes:
if i % p == 0:
break
if i % p:
primes.append(i)
print("This will be printed to screen:", i, flush=True)
print(i, file=outfile, flush=True) # this will go to the main process
i += 2
time.sleep(.005)
主文件
import subprocess
import os
import tempfile
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'fifo') # Temporary filename
os.mkfifo(filename) # Create FIFO
proc = subprocess.Popen(["python3", "test.py", filename], shell=False)
with open(filename, 'rt', 1) as fifo:
primes = []
while proc.poll() is None:
line = fifo.readline()
if line:
new_prime = int(line)
primes.append(new_prime)
if new_prime > 1000:
print("Threshold achieved", line)
proc.terminate()
else:
print("new prime:", new_prime)
print(primes)
pass
os.remove(filename)
os.rmdir(tmpdir)