[英]return values from exceptions in multiprocessing
我正在调用一个函数task(url, param1, param2)
,该函数将API调用的结果返回到url = url
或url
名称(如果API调用不起作用)。 我的task
看起来像:
def task(url, param1, param2):
try:
make_api_call(url, param1, param2)
except ValueError as e:
print("val error")
return url
现在,我想将task
应用于100个网址的列表,并开始对它们进行multiprocessing
:
import multiprocessing as mp
def run_tasks(urls, param1, param2):
jobs = []
for i in range(len(urls)):
process = mp.Process(target=task, args=(urls[i], param1, param2))
jobs.append(process)
## catch error processes
error_urls = []
## start processes
for j in jobs:
j.start()
## finish processes
for j in jobs:
j.join()
从上面的run_tasks
,如何返回给我ValueError
的url
列表? 我尝试了error_urls.append(j.join())
,但这没有用。
有两种方法可以从过程中获取结果。
方法1.使用Manager
list
。 您无需使用锁在进程之间进行同步。
from multiprocessing import Process, Manager
def task(url, param1, param2, error_list):
try:
make_api_call(url, param1, param2)
except ValueError as e:
print("val error")
error_list.append(url)
def run_tasks(urls, param1, param2):
error_list = Manager().list()
jobs = []
for i in range(len(urls)):
process = Process(target=task, args=(urls[i], param1, param2, error_list))
jobs.append(process)
## start processes
for j in jobs:
j.start()
## finish processes
for j in jobs:
j.join()
方法2。使用concurrent.futures
ProcessPoolExecutor
。 此方法易于理解,并且代码更少。
from concurrent import futures
def task(url, param1, param2):
try:
make_api_call(url, param1, param2)
except ValueError as e:
print("val error")
return url
def runt_tasks(urls, param1, param2):
with futures.ProcessPoolExecutor() as executor:
result = executor.map(task, urls, [param1] * len(urls), [param2] * len(urls))
error_list = [item for item in result if item is not None]
最后,从问题描述开始。 这是一个IO敏感问题。 我建议您使用ThreadPoolExecutor
。 当您执行IO操作时,线程将释放GIL以让其他线程运行。 对于CPU敏感的问题,最好使用ProcessPoolExecutor
。 而asyncio
是在Python 3中进行并发编程的另一种选择。
尝试共享内存。 使用此multiprocessing.sharedctypes.Array(typecode_or_type, size_or_initializer, *args[, lock])
您可以在run_tasks中定义它
from multiprocessing import Process, Lock
from multiprocessing.sharedctypes import Array
lock = Lock()
error_urls = Array(c_char_p, [], lock = lock)
和
def task(url, param1, param2):
try:
make_api_call(url, param1, param2)
except ValueError as e:
print("val error")
error_urls.append(url)
作为Array()的文档:
与RawArray()相同, 不同之处在于, 取决于锁的值,可以返回进程安全的同步包装而不是原始ctypes数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.