如何使用 concurrent.future 池线程执行器为 Subprocess.run 设置 shell=True
How to set shell=True for a Subprocess.run with a concurrent.future Pool Threading Executor
我尝试在 Python 中使用 concurrent.future
多线程和 subprocess.run
来启动外部 Python 脚本。但是我在 subprocess.run().
的 shell=True
部分遇到了一些麻烦
这里是外部代码的例子,姑且称之为test.py:
#! /usr/bin/env python3
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-x', '--x_nb', required=True, help='the x number')
parser.add_argument('-y', '--y_nb', required=True, help='the y number')
args = parser.parse_args()
print('result is {} when {} multiplied by {}'.format(int(args.x_nb) * int(args.y_nb),
args.x_nb,
args.y_nb))
在我的主要 python 脚本中,我有:
#! /usr/bin/env python3
import subprocess
import concurrent.futures
import threading
...
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append(cmd)
# just as an example, this line works fine
subprocess.run(args_list[0], shell=True)
# this multithreading is not working
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(subprocess.run, args_list)
这里的问题是我无法将 shell=True
选项传递给 executor.map
。
我已经试过了没有成功:
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append((cmd, eval('shell=True'))
或
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append((cmd, 'shell=True'))
有人知道如何解决这个问题吗?
我认为 map
方法不能直接调用带有关键字参数的函数,但有 2 个简单的解决方案可以解决您的问题。
解决方案 1:使用 lambda 设置所需的额外关键字参数
lambda 基本上是一个调用您的真实函数并传递参数的小函数。如果关键字参数是固定的,这是一个很好的解决方案。
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(lambda args: subprocess.run(args, shell=True), args_list)
方案二:使用executor.submit将函数提交给执行者
submit
方法允许您为目标函数指定参数和关键字参数。
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
for args in args_list:
executor.submit(subprocess.run, args, shell=True)
我尝试在 Python 中使用 concurrent.future
多线程和 subprocess.run
来启动外部 Python 脚本。但是我在 subprocess.run().
shell=True
部分遇到了一些麻烦
这里是外部代码的例子,姑且称之为test.py:
#! /usr/bin/env python3
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-x', '--x_nb', required=True, help='the x number')
parser.add_argument('-y', '--y_nb', required=True, help='the y number')
args = parser.parse_args()
print('result is {} when {} multiplied by {}'.format(int(args.x_nb) * int(args.y_nb),
args.x_nb,
args.y_nb))
在我的主要 python 脚本中,我有:
#! /usr/bin/env python3
import subprocess
import concurrent.futures
import threading
...
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append(cmd)
# just as an example, this line works fine
subprocess.run(args_list[0], shell=True)
# this multithreading is not working
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(subprocess.run, args_list)
这里的问题是我无法将 shell=True
选项传递给 executor.map
。
我已经试过了没有成功:
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append((cmd, eval('shell=True'))
或
args_list = []
for i in range(10):
cmd = './test.py -x {} -y 2 '.format(i)
args_list.append((cmd, 'shell=True'))
有人知道如何解决这个问题吗?
我认为 map
方法不能直接调用带有关键字参数的函数,但有 2 个简单的解决方案可以解决您的问题。
解决方案 1:使用 lambda 设置所需的额外关键字参数
lambda 基本上是一个调用您的真实函数并传递参数的小函数。如果关键字参数是固定的,这是一个很好的解决方案。
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(lambda args: subprocess.run(args, shell=True), args_list)
方案二:使用executor.submit将函数提交给执行者
submit
方法允许您为目标函数指定参数和关键字参数。
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
for args in args_list:
executor.submit(subprocess.run, args, shell=True)