如何与ThreadPoolExecutor并行运行代码?

2024-09-29 01:23:47 发布

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

嗨,我真的是线程新手,这让我很困惑,我怎么能并行运行这段代码

def search_posts(page):

    page_url = f'https://jsonplaceholder.typicode.com/posts/{page}'
    req = requests.get(page_url)
    res = req.json()
    
    title = res['title']
    
    return title



page = 1

while True:

    with ThreadPoolExecutor() as executer:
        t = executer.submit(search_posts, page)

        title = t.result()

        print(title)

    if page == 20:
        break

    page += 1

另一个问题是,为了理解线程是如何工作的,我是否需要学习操作系统


Tags: 代码httpsurlsearchtitledefpageres
1条回答
网友
1楼 · 发布于 2024-09-29 01:23:47

这里的问题是,您正在为每个页面创建一个新的ThreadPoolExecutor。要并行执行操作,请仅创建一个ThreadPoolExecutor并使用其map方法:

import concurrent.futures as cf
import requests


def search_posts(page):
    page_url = f'https://jsonplaceholder.typicode.com/posts/{page}'
    res = requests.get(page_url).json()
    return res['title']


if __name__ == '__main__':
    with cf.ThreadPoolExecutor() as ex: 
        results = ex.map(search_posts, range(1, 21))
    for r in results:
        print(r)

请注意,使用if __name__ == '__main__'包装器是使代码更具可移植性的一个好习惯


使用线程时要记住一件事; 如果您使用的是CPython(最常见的python.org的Python实现),那么线程实际上不会并行运行

为了降低内存管理的复杂性,每次只能有一个线程在CPython中执行Python字节码。这是由CPython中的全局解释器锁(“GIL”)强制执行的

好消息是,使用requests获取网页将花费大部分时间使用网络I/O。一般来说,GIL是在I/O期间发布的

但是,如果您在工作函数中进行计算(即执行Python字节码),则应该使用ProcessPoolExecutor

如果使用ProcessPoolExecutor并且在ms windows上运行,则需要使用if __name__ == '__main__'包装器,因为在这种情况下,Python必须能够import运行主程序,而不会产生副作用

相关问题 更多 >