Python多线程并发时通过线程池限流


	Python多线程并发时通过线程池限流
[编程语言教程]

Python支持多线程,但是由于GIL的限制并不能无限制的开启子线程。

通过semaphore我们可以控制子线程对于共享资源的访问,即可以阻塞一些子线程直到有空余的semaphore资源,但是并不能实际限制子线程数。

当我们需要开启成千上万个子线程时,很多时候并不希望这些子线程同时执行(可能受限于系统资源or后端数据库),而是更希望一次性执行一批子线程,然后有空余资源时补充一批继续执行。

在Python2中,一种变通的方法是自己设置一个简易的线程池,如下所示:

if __name__ == ‘__main__‘:
    max_workers = 50
    all_resouces = get_all_resouces()
    thread_pool = {}
    i = 0
    while i < len(all_resouces):
        if len(thread_pool) < max_workers:
            thd = Thread(target=handle_resource, args=(all_resouces[i],), name=all_resouces[i])
            thd.start()
            thread_pool[i] = thd
            i += 1
        else:
            sleep(3)
            for thd_index,thd in thread_pool.items():
                if not thd.is_alive():
                    thread_pool.pop(thd_index)
    for thd in thread_pool.values():
        thd.join()
# 这里把线程池定义为dict而非list是因为遍历list时对list本身做remove会导致线程池满后清除死线程的效率降低一半。
# 这个BUG是因为for遍历list其实是根据下标索引来遍历的,每当删除一个元素就会导致后边的下标整体-1,这会导致下一次遍历时跳过被删除位置的元素
# 这个BUG有多种处理方式,例如list copy,queue等等,在stackoverflow上也有诸多讨论,这里不过多描述。
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » Python多线程并发时通过线程池限流