考虑以下代码示例:
import multiprocessing
import requests
session = requests.Session()
data_to_be_processed = [...]
def process(arg):
# do stuff with arg and get url
response = session.get(url)
# process response and generate data...
return data
with multiprocessing.Pool() as pool:
results = pool.map(process, data_to_be_processed)
例如,Session
被分配为全局变量,因此在创建进程后Pool
它将被复制到每个子流程中。我不确定会话是否是线程安全的,也不知道会话中的池化是如何工作的,所以我想为池中的每个进程分配单独的会话对象.
我知道,我可以使用requests.get(url)
代替session.get(url)
,但我想使用 session 并且我也在考虑使用requests-html
(https://html.python-requests.org/ https://html.python-requests.org/).
我对 python 的多处理不太熟悉,到目前为止我只使用了池,因为它对我来说是并行处理数据而没有关键部分的最佳解决方案,所以我对不同的解决方案持开放态度。
有没有一种方法可以干净、直接地做到这一点?
简短的回答:您可以使用全局命名空间在之间共享数据初始化器 and func:
import multiprocessing
import requests
session = None
data_to_be_processed = [...]
def init_process():
global session
session = requests.Session()
def process(arg):
global session
# do stuff with arg and get url
response = session.get(url)
# process response and generate data...
return data
with multiprocessing.Pool(initializer=init_process) as pool:
results = pool.map(process, data_to_be_processed)
长答案:
Python 使用三种可能的方法之一启动方法 https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods。它们都将父进程和子进程之间的内存对象分开。在我们的例子中,这意味着运行的进程的全局命名空间发生变化Pool()不会传播回父进程,也不会传播回兄弟进程。
对于对象销毁,我们可以依靠垃圾收集器,它会在子进程完成其工作后介入。缺少显式关闭方法多处理.Pool()使得它不可能与不可被 GC 破坏的对象一起使用(例如Pool()本身 - 请参阅警告here https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool)
判断从请求文档 https://requests.readthedocs.io/en/master/user/advanced/#session-objects,使用起来完全没问题请求.Session没有明确的 close() 。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)