Run subprocess asynchronously#
默认情况下 subprocess.run() 是 sync 模式. 也就是一条命令执行完毕后才会执行下一条命令. 但是有时候我们需要异步执行多条命令, 这时候我们可以使用 subprocess.Popen() 来实现.
例如在下面的例子中我们有两个脚本, 分别是 sleep 5 秒和 10 秒.
script1.py
1import time
2
3print("start script 1")
4time.sleep(5)
5print("end script 1")
script2.py
1import time
2
3print("start script 2")
4time.sleep(10)
5print("end script 2")
我们可以用下面的脚本来异步执行这两个脚本. 总共花费了 10 秒钟.
subprocess_run_async_mode_example.py
1# -*- coding: utf-8 -*-
2
3import subprocess
4from datetime import datetime
5
6def run_script_async(script):
7 process = subprocess.Popen(['python', script])
8 return process
9
10# Start the timer
11start_time = datetime.now()
12
13# Run script1 and script2 concurrently
14script1_process = run_script_async("script3.py")
15script2_process = run_script_async("script4.py")
16
17# Wait for both scripts to complete
18response1 = script1_process.wait()
19response2 = script2_process.wait()
20print(f"{response1 = }")
21print(f"{response2 = }")
22
23# Calculate the total execution time
24execution_time = (datetime.now() - start_time).total_seconds()
25
26print(f"Total execution time: {execution_time:.2f} seconds")
还是用 subprocess_run_async_mode_example.py 脚本, 但是我们换成下面两个 script, 其中一个会运行到一半抛出异常. 你可以看到由于是异步执行, 所以另一个脚本还是会继续执行.
script3.py
1import time
2
3print("start script 3")
4time.sleep(5)
5raise Exception("script 3 raises an error!")
6print("end script 3")
script4.py
1import time
2
3print("start script 4")
4time.sleep(10)
5print("end script 4")