Python3.7多线程策略

2024-10-03 09:07:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个工作量,由一个非常慢的查询组成,该查询返回大量需要解析和计算的数据,所有这些都是在一个循环中进行的。基本上,它看起来是这样的:

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


Tags: 数据in数据库for过程sec线程about
3条回答

很难说这是否以及有多大帮助(因为我没有什么要测试的…),但你可以试试^{}。它为您处理所有脏活,您可以自定义进程数、块大小等

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)

在这里的示例中,我使用^{}方法,但根据您的需要,您可能希望使用imapmap_async

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

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

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

相关问题 更多 >