繁体   English   中英

如何为多处理池中的单个进程分配 python 请求会话?

[英]How to assign python requests sessions for single processes in multiprocessing pool?

考虑以下代码示例:

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创建进程后,它将被复制到每个子进程中。 我不确定会话是否是线程安全的,也不知道会话中的池是如何工作的,所以我想为 pool 中的每个进程分配单独的会话对象

我知道,我可以只使用requests.get(url)而不是session.get(url) ,但我想使用 session 并且我也在考虑使用requests-html ( https://html.python- requests.org/ )。

我对 python 的多处理不是很熟悉,到目前为止我只使用了池,因为它是我认为并行处理数据而没有临界区的最佳解决方案,所以我对不同的解决方案持开放态度。

有没有办法做到干净和直接?

简短回答:您可以使用全局命名空间在initializerfunc之间共享数据:

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 使用三种可能的启动方法之一 它们都将父进程和子进程之间的内存对象分开。 在我们的例子中,这意味着Pool()运行的进程的全局命名空间中的更改不会传播回父进程,也不会传播回兄弟进程。

对于对象销毁,我们可以依靠垃圾收集器,一旦子进程完成它的工作,它就会介入。 multiprocessing.Pool() 中缺少显式关闭方法使得无法与 GC 不可破坏的对象一起使用(如Pool()本身 - 请参阅此处的警告)从请求文档来看,使用requests.Session是完全可以的没有明确的 close() 就可以了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM