Python 3.7 多线程策略



>我有一个工作负载,它包含一个非常慢的查询,该查询返回了大量必须解析和计算的数据,所有这些都在一个循环中。基本上,它看起来像这样:

for x in lastTenYears
myData = DownloadData(x)             # takes about   ~40-50 [sec]
parsedData.append(ParseData(myData)) # takes another +30-60 [sec]

我相信您已经注意到,如果我可以在线程上运行数据解析,我可以在解析发生时下载下一批数据。

如何实现这种操作的并行性?

理想情况下,我希望始终下载 1 个线程,并有 N 个线程进行解析。下载部分实际上是对数据库的查询,所以有一堆并行的是不好的......

详细信息:
数据的解析受到严重的 CPU 限制,由
原始数学计算组成,没有其他内容。

使用 Python 3.7.4

1) 使用线程安全队列。在顶层定义

my_queue = Queue.FIFOQueue()
parsedData = []

2) 在第一个线程上,开始数据加载

my_queue.put(DownloadData(x))

在第二个线程上

if not (my_queue.empty()):
myData = my_queue.get()
parsedData.append(ParseData(myData))

如果您的程序受 CPU 限制,由于 GIL(全局解释器锁),您将很难在其他线程中执行任何其他操作。

以下是一篇文章的链接,可以帮助您理解该主题:https://opensource.com/article/17/4/grok-gil

在子流程中下载数据很可能是最好的方法。

很难说这是否以及实际上有多大帮助(因为我没有什么可测试的......),但你可以尝试一个multiprocessing.Pool。它为您处理所有繁琐的工作,您可以自定义进程数量、块大小等。

from multiprocessing import Pool
def worker(x):
myData = DownloadData(x)
return ParseData(myData)
if __name__ == "__main__":
processes = None  # defaults to os.cpu_count()
chunksize = 1
with Pool(processes) as pool:
parsedData = pool.map(worker, lastTenYears, chunksize)

在这里,我使用map方法的示例,但根据您的需要,您可能需要使用imapmap_async.

如何实现这种操作的并行性

第一步是要意识到,上面请求的用例不是[PARALLEL]代码执行,而是无序一批资源使用策略限制执行严格的对序列:

Firsta-remote-[DB-Query](返回(引用)大量数据)Next-a-local-[CPU-process]((引用)刚刚返回的大量数据)

第一个的延迟可以被屏蔽
(如果允许,但不允许- 由于不会使数据库主机过载),
第二个不的延迟(可以启动但下一个 I/O 绑定的数据库查询,但前提是不违反保留数据库机器的规则,但在轻微的工作负载下)。

我相信您已经注意到 ,如果我可以在线程上运行数据解析,我可以在解析发生时下载下一批数据。

现在是让事情变得清晰和合理的时候了:

事实:

A)
在python-GIL-lock控制的生态系统中,CPU绑定的任务永远不会在N线程中运行得更快(从始至终,正如Guido ROSSUM所表达的那样),
因为GIL-lock强制执行重新[SERIAL]化,所以"工作"的线程越多,实际上等待获取GIL-lock的线程就越多,然后他们"得到"它,但需要1 / ( N + 1 )-时间的分数,由于 GIL-lock 警务再次纯[SERIAL]持续时间N * ( 30 - 60 ) [sec]

B )I/O 绑定任务卸载到基于完整进程的并发执行是没有意义的,因为 python 进程的完整副本(在 Windows 中也与子进程实例化期间用所有数据复制整个 python 解释器状态)
是没有意义的,因为有更智能的 I/O 绑定处理技术(其中 GIL-lock 不会受到太大伤害。

C)
N-parsing : 1-querying的整个概念主要是错误的- 最大可实现的目标是掩盖I/O进程的延迟(有意义),但在这里每个查询都采用这些所述~ 40-50 [sec]因此在下次运行这些所述~ 40-50 [sec]之前,这里将永远不存在第二个要解析的数据包, 因此
T0 + ~ 80~100 [sec]之前,没有第二个工人会得到任何可以解析的东西- 所以人们可以梦想让 N-(未绑定)工作的愿望(但有他们但实际上在等待数据)是可能的,但非常反生产(对于N-(GIL-MUTEX-ED)-"WAITING"-AGENTS 来说更糟)。

最新更新