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

Posted

技术标签:

【中文标题】如何为多处理池中的单个进程分配 python 请求会话?【英文标题】:How to assign python requests sessions for single processes in multiprocessing pool? 【发布时间】:2019-03-14 07:27:34 【问题描述】:

考虑以下代码示例:

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),但我想使用会话,我也在考虑使用requests-html (https://html.python-requests.org/)。

我对 python 的多处理不是很熟悉,到目前为止我只使用了池,因为它是我认为最好的解决方案,可以在没有关键部分的情况下并行处理数据,所以我对不同的解决方案持开放态度。

有没有办法做到简洁明了?

【问题讨论】:

如果你有多个通话,一个会话是有意义的。我只看到一个。 假设data_to_be_processed 将包含 100 000 个项目,那么我将在单个会话中进行 100 000 次调用...如果池中有 4 个进程,那么我希望有 25 000 个调用每个Session 对象。 您需要一个 Session 来做什么(与仅使用 requests.get() 相比)? 我要查询的所有 url 都在同一个网站上,所以我认为它会为我的程序和站点服务器节省一些处理时间。 另外,正如我之前提到的,在某些时候我想使用requests-html,其中只有会话可用于查询。 【参考方案1】:

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

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

【讨论】:

以上是关于如何为多处理池中的单个进程分配 python 请求会话?的主要内容,如果未能解决你的问题,请参考以下文章

Python - 多进程池中的 make_archive zip 无法正常工作

多进程池中的 apply_async 问题

如何为 Windows 中的进程分配超过 2GB 的内存?

多处理池是不是为每个进程提供相同数量的任务,或者它们是不是被分配为可用?

在多处理中如何将 CPU 内核分配给 python 进程?

Python中的多处理:处理多个工作线程