精华内容
下载资源
问答
  • 主要介绍了python线程池(threadpool)模块使用笔记详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 本文实例讲述了Python线程池模块ThreadPoolExecutor用法。分享给大家供大家参考,具体如下: python3内置的有Threadingpool和ThreadPoolExecutor模块,两个都可以做线程池,当然ThreadPoolExecutor会更好用一些,...
  • 本文为大家分享了threadpool线程池中所有的操作,供大家参考,具体内容如下 首先介绍一下自己使用到的名词: 工作线程(worker):创建线程池时,按照指定的线程数量,创建工作线程,等待从任务队列中get任务; 任务...
  • 本文实例讲述了Python 线程池用法。分享给大家供大家参考,具体如下: # -*- coding:utf-8 -*- #! python3 ''' Created on 2019-10-2 @author: Administrator ''' from concurrent.futures import ...
  • 可以使用python语言自己实现线程池,或者可以使用第三方包threadpool线程池包,本主题主要介绍threadpool的使用以及其里面的具体实现。 1、安装 使用安装: pip installthreadpool 2、使用  (1)引入threadpool...
  • Python线程池

    2020-08-26 15:37:30
    一、线程池 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池线程池在...

    一、线程池

    系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。

    线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

    此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python 解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

    二、 线程池的使用

    线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,即 ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。

    如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。

    Exectuor 提供了如下常用方法:

    • submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs 代表以关键字参数的形式为 fn 函数传入参数。
    • map(func, *iterables, timeout=None, chunksize=1):该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理。
      shutdown(wait=True):关闭线程池。

    程序将 task 函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future 类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此,线程执行的函数相当于一个“将来完成”的任务,所以 Python 使用 Future 来代表。
    实际上,在 Java 的多线程编程中同样有 Future,此处的 Future 与 Java 的 Future 大同小异。

    Future 提供了如下方法:

    • cancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True。
    • cancelled():返回 Future 代表的线程任务是否被成功取消。
    • running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。
    • done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。
    • result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。
    • exception(timeout=None):获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None。
    • add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该 fn 函数。

    在用完一个线程池后,应该调用该线程池的 shutdown() 方法,该方法将启动线程池的关闭序列。调用 shutdown() 方法后的线程池不再接收新任务,但会将以前所有的已提交任务执行完成。当线程池中的所有任务都执行完成后,该线程池中的所有线程都会死亡。

    使用线程池来执行线程任务的步骤如下:

    1. 调用 ThreadPoolExecutor 类的构造器创建一个线程池。
    2. 定义一个普通函数作为线程任务。
    3. 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。
    4. 当不想提交任何任务时,调用 ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程池。

    下面程序示范了如何使用线程池来执行线程任务:

    from concurrent.futures import ThreadPoolExecutor
    import threading
    import time
    # 定义一个准备作为线程任务的函数
    def action(max):
        my_sum = 0
        for i in range(max):
            print(threading.current_thread().name + '  ' + str(i))
            my_sum += i
        return my_sum
    # 创建一个包含2条线程的线程池
    pool = ThreadPoolExecutor(max_workers=2)
    # 向线程池提交一个task, 50会作为action()函数的参数
    future1 = pool.submit(action, 50)
    # 向线程池再提交一个task, 100会作为action()函数的参数
    future2 = pool.submit(action, 100)
    # 判断future1代表的任务是否结束
    print(future1.done())
    time.sleep(3)
    # 判断future2代表的任务是否结束
    print(future2.done())
    # 查看future1代表的任务返回的结果
    print(future1.result())
    # 查看future2代表的任务返回的结果
    print(future2.result())
    # 关闭线程池
    pool.shutdown()
    

    上面程序中,第 13 行代码创建了一个包含两个线程的线程池,接下来的两行代码只要将 action() 函数提交(submit)给线程池,该线程池就会负责启动线程来执行 action() 函数。这种启动线程的方法既优雅,又具有更高的效率。

    当程序把 action() 函数提交给线程池时,submit() 方法会返回该任务所对应的 Future 对象,程序立即判断 futurel 的 done() 方法,该方法将会返回 False(表明此时该任务还未完成)。接下来主程序暂停 3 秒,然后判断 future2 的 done() 方法,如果此时该任务已经完成,那么该方法将会返回 True。

    程序最后通过 Future 的 result() 方法来获取两个异步任务返回的结果。
    读者可以自己运行此代码查看运行结果,这里不再演示。

    当程序使用 Future 的 result() 方法来获取结果时,该方法会阻塞当前线程,如果没有指定 timeout 参数,当前线程将一直处于阻塞状态,直到 Future 代表的任务返回。
    获取执行结果
    前面程序调用了 Future 的 result() 方法来获取线程任务的运回值,但该方法会阻塞当前主线程,只有等到钱程任务完成后,result() 方法的阻塞才会被解除。

    如果程序不希望直接调用 result() 方法阻塞线程,则可通过 Future 的 add_done_callback() 方法来添加回调函数,该回调函数形如 fn(future)。当线程任务完成后,程序会自动触发该回调函数,并将对应的 Future 对象作为参数传给该回调函数。

    下面程序使用 add_done_callback() 方法来获取线程任务的返回值:

    from concurrent.futures import ThreadPoolExecutor
    import threading
    import time
    # 定义一个准备作为线程任务的函数
    def action(max):
        my_sum = 0
        for i in range(max):
            print(threading.current_thread().name + '  ' + str(i))
            my_sum += i
        return my_sum
    # 创建一个包含2条线程的线程池
    with ThreadPoolExecutor(max_workers=2) as pool:
        # 向线程池提交一个task, 50会作为action()函数的参数
        future1 = pool.submit(action, 50)
        # 向线程池再提交一个task, 100会作为action()函数的参数
        future2 = pool.submit(action, 100)
        def get_result(future):
            print(future.result())
        # 为future1添加线程完成的回调函数
        future1.add_done_callback(get_result)
        # 为future2添加线程完成的回调函数
        future2.add_done_callback(get_result)
        print('--------------')
    

    上面主程序分别为 future1、future2 添加了同一个回调函数,该回调函数会在线程任务结束时获取其返回值。

    主程序的最后一行代码打印了一条横线。由于程序并未直接调用 future1、future2 的 result() 方法,因此主线程不会被阻塞,可以立即看到输出主线程打印出的横线。接下来将会看到两个新线程并发执行,当线程任务执行完成后,get_result() 函数被触发,输出线程任务的返回值。

    另外,由于线程池实现了上下文管理协议(Context Manage Protocol),因此,程序可以使用 with 语句来管理线程池,这样即可避免手动关闭线程池,如上面的程序所示。

    此外,Exectuor 还提供了一个 map(func, *iterables, timeout=None, chunksize=1) 方法,该方法的功能类似于全局函数 map(),区别在于线程池的 map() 方法会为 iterables 的每个元素启动一个线程,以并发方式来执行 func 函数。这种方式相当于启动 len(iterables) 个线程,井收集每个线程的执行结果。

    例如,如下程序使用 Executor 的 map() 方法来启动线程,并收集线程任务的返回值:

    from concurrent.futures import ThreadPoolExecutor
    import threading
    import time
    # 定义一个准备作为线程任务的函数
    def action(max):
        my_sum = 0
        for i in range(max):
            print(threading.current_thread().name + '  ' + str(i))
            my_sum += i
        return my_sum
    # 创建一个包含4条线程的线程池
    with ThreadPoolExecutor(max_workers=4) as pool:
        # 使用线程执行map计算
        # 后面元组有3个元素,因此程序启动3条线程来执行action函数
        results = pool.map(action, (50, 100, 150))
        print('--------------')
        for r in results:
            print(r)
    

    上面程序使用 map() 方法来启动 3 个线程(该程序的线程池包含 4 个线程,如果继续使用只包含两个线程的线程池,此时将有一个任务处于等待状态,必须等其中一个任务完成,线程空闲出来才会获得执行的机会),map() 方法的返回值将会收集每个线程任务的返回结果。

    运行上面程序,同样可以看到 3 个线程并发执行的结果,最后通过 results 可以看到 3 个线程任务的返回结果。

    通过上面程序可以看出,使用 map() 方法来启动线程,并收集线程的执行结果,不仅具有代码简单的优点,而且虽然程序会以并发方式来执行 action() 函数,但最后收集的 action() 函数的执行结果,依然与传入参数的结果保持一致。也就是说,上面 results 的第一个元素是 action(50) 的结果,第二个元素是 action(100) 的结果,第三个元素是 action(150) 的结果。

    展开全文
  • 主要介绍了Python 线程池的相关资料,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
  • 今天小编就为大家分享一篇python自定义线程池控制线程数量的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • python线程池及其原理和使用 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用...

    python线程池及其原理和使用

    • 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。
    • 线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

    此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python 解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

    线程池的使用

    • 线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,即
      ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor
      用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。

    如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。

    Exectuor 提供了如下常用方法:

    • submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs
      代表以关键字参数的形式为 fn 函数传入参数。 map(func, *iterables, timeout=None,
      chunksize=1):该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对
      iterables 执行 map 处理。 shutdown(wait=True):关闭线程池。
    • 程序将 task 函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future
      类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此,线程执行的函数相当于一个“将来完成”的任务,所以
      Python 使用 Future 来代表。

    Future 提供了如下方法:

    • cancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回
      False;否则,程序会取消该任务,并返回 True。

    • cancelled():返回 Future 代表的线程任务是否被成功取消。

    • running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。

    • done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。

    • result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future
      代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。

    • exception(timeout=None):获取该 Future
      代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None。

    • add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该
      fn 函数。

    在用完一个线程池后,应该调用该线程池的 shutdown() 方法,该方法将启动线程池的关闭序列。调用 shutdown() 方法后的线程池不再接收新任务,但会将以前所有的已提交任务执行完成。当线程池中的所有任务都执行完成后,该线程池中的所有线程都会死亡。

    使用线程池来执行线程任务的步骤如下:

    • 调用 ThreadPoolExecutor 类的构造器创建一个线程池。 定义一个普通函数作为线程任务。
    • 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。 当不想提交任何任务时,调用
      ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程池。
      ThreadPoolExecutor(线程池)

    线程池一些知识点:

    1. python中ThreadPoolExecutor(线程池)是concurrent.futures模块下的,主线程中可以获取某一个线程执行的状态或者某一个任务执行的状态及返回值。
    2. 通过submit返回的是一个future对象,它是一个未来可期的对象,通过它可以获悉线程的状态
    3. 通过submit提交函数到进程池中,submit(函数名,参数)
    4. 通过wait()判断线程执行的状态:wait(fs, timeout=None,
      return_when=ALL_COMPLETED),wait接受3个参数,fs表示执行的task序列;timeout表示等待的最长时间,超过这个时间即使线程未执行完成也将返回;return_when表示wait返回结果的条件,默认为ALL_COMPLETED全部执行完成再返回
      http的是IO请求,所以用线程
      编写方法一:直接返回处理
    from concurrent.futures import ThreadPoolExecutor
    import requests
    
    pool = ThreadPoolExecutor(10)
    
    def task(url):
        response = requests.get(url)
        print(url,response)
    
    
    
    url_list = (
        "https://www.bing.com",
        "https://www.shihu.com",
        "https://www.sina.com",
        "https://www.baidu.com",
        "https://www.cnblogs.com",
        "https://music.163.com/#"
    )
    
    for url in url_list:
        pool.submit(task,url)
    
    pool.shutdown(wait=True)
    

    result

    https://www.bing.com <Response [200]>
    https://www.baidu.com <Response [200]>
    https://www.cnblogs.com <Response [200]>
    https://music.163.com/# <Response [200]>
    https://www.sina.com <Response [200]>
    

    编写方法二:通过回调函数进行处理

    from concurrent.futures import ThreadPoolExecutor
    import requests
    
    pool = ThreadPoolExecutor(10)
    
    def task(url):
        response = requests.get(url)   #下载页面
        return response
    
    def done(future,*args,**kwargs):
        response = future.result()   #取得future对象进行操作
        print(response.status_code,response.content)
    
    url_list = (
        "https://www.bing.com",
        "https://www.jd.com",
        "https://www.sina.com",
        "https://www.baidu.com",
        "https://www.cnblogs.com",
        "https://music.163.com/#"
    )
    
    for url in url_list:
        v = pool.submit(task,url)    #获得一个返回值,其实就是访问url的响应
        v.add_done_callback(done)
    
    展开全文
  • url(url): print('正在访问',url) res = requests.get(url=url,headers=headers) print('访问状态:',res.status_code) time.sleep(2) while True: pool = Pool(4) pool.map(get_url,urls) 以上就是线程池pool.map的...
    import requests
    import time
    from multiprocessing.dummy import Pool
    
    headers = {
        'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
    }
    
    urls = [
        'https://sp1.baidu.com/',
        'https://sp1.baidu.com/',
        'https://sp1.baidu.com/',
        'https://www.baidu.com/'
    ]
    
    
    def get_url(url):
        print('正在访问',url)
        res = requests.get(url=url,headers=headers)
        print('访问状态:',res.status_code)
        time.sleep(2)
    
    
    while True:
        pool = Pool(4)
        pool.map(get_url,urls)
    

    以上就是线程池pool.map的方法,比较简单。Pool(9)括号里面写多少就是多少个线程

    展开全文
  • 线程池的作用线程池实现 线程池的作用 线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池线程池就会启动一...当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python ...

    线程池的作用

    线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。
    有时候,我们无法知道
    此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python 解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。
    比如我在U盘扫描病毒那里已经实现,假如定义了5个线程,扫描20个文件夹,此时会同时扫描5个文件夹,还剩下15个,被扫的5个文件夹中,有一个文件夹比较小,会比较快被扫完,假如过了5秒后,这个文件夹被扫描完了,此时有一个线程是空着的,则会去扫第6个文件夹,此时还是5个线程,此时就剩下14个文件夹未扫咯,这些操作都是自动调度的,我们不用手动干预,创建多线程还是有挺多方式的,下面分别介绍。

    线程池实现

    1、threadpool实现线程池

    #encoding:utf-8
    import time
    import threadpool
    import random
    import threading
    
    def sayhello(str):  #执行方法
        sleep_seconds=random.randint(1, 3)
        print '线程名称:%s,参数:%s,睡眠时间:%s'%(threading.current_thread().name,str,sleep_seconds)
        time.sleep(sleep_seconds)
    
    name_list =['aa','bb','cc','dd']    #总共需要执行4个线程
    start_time = time.time()    #开始时间
    pool = threadpool.ThreadPool(2)     #创建2个线程
    #创建请求列表
    requests = threadpool.makeRequests(sayhello, name_list)
    for req in requests:
        pool.putRequest(req)    #将每个请求添加到线程池中
    pool.wait()  #等待线程执行完后再执行主线程
    print '总共运行时间:%d second'% (time.time()-start_time)
    

    结果如下:
    在这里放到放到图片描述
    我们可以看到,线程池总共创建了2个线程去执行4个任务,Thread-1睡眠时间为3秒,Thread-2睡眠时间为2秒,也就是说,Thread-2会首先执行完,之后线程池会自动调度下一个任务赋给Thread-2,这样就实现了线程池控制线程数量并自动调度线程的功能!

    2、ThreadPoolExecutor实现线程池

    threadpool是一个比较老的模块了,现在虽然还有一些人在用,但已经不再是主流了,关于python多线程,现在已经开始步入未来(future模块)了,使用concurrent.futures模块,这个模块是python3中自带的模块,但是,python2.7以上版本也可以安装使用,具体使用方式如下(Python2.7安装:pip install futures)

    #encoding:utf-8
    from concurrent.futures import ThreadPoolExecutor
    import threading
    import random
    import time
    
    #线程任务
    def task(i):
        sleep_seconds = random.randint(1, 3)    #随机睡眠时间
        print '线程名称:%s,参数:%s,睡眠时间:%s' % (threading.current_thread().name, i, sleep_seconds)
        time.sleep(sleep_seconds)   #定义睡眠时间
    
    #创建一个包含2条线程的线程池
    pool = ThreadPoolExecutor(max_workers = 2)  #定义两个线程
    #向线程池提交5个任务
    for i in range(5):
        future1 = pool.submit(task, i)  #任务加入线程池
    pool.shutdown()
    

    运行结果:
    在这里插入图片描述
    3、自定义线程池
    有时候,我们可以手动构建线程池,不依赖上面的模块
    任务获取和执行:

     (1)任务加入队列,等待线程来获取并执行。

     (2)按需生成线程,每个线程循环取任务。

    线程销毁:

     (1)获取任务是终止符时,线程停止。

     (2)线程池close()时,向任务队列加入和已生成线程等量的终止符。

     (3)线程池terminate()时,设置线程下次任务取到为终止符。
     
     运行流程图如下:
    在这里插入图片描述

    # -*- coding:utf-8 -*-
    
    import Queue
    import threading
    import contextlib
    StopEvent = object()
    class ThreadPool(object):
    
        def __init__(self, max_num):
            self.q = Queue.Queue()#存放任务的队列
            self.max_num = max_num#最大线程并发数
    
            self.terminal = False#如果为True 终止所有线程,不再获取新任务
            self.generate_list = [] #已经创建的线程
            self.free_list = []#闲置的线程,当无空闲的线程,且有新任务调用了run方法,则需要创建新的线程
    
        def run(self, func, args, callback=None):
            """
            线程池执行一个任务
            :param func: 任务函数
            :param args: 任务函数所需参数
            :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
            :return: 如果线程池已经终止,则返回True否则None
            """
    
            if len(self.free_list) == 0 and len(self.generate_list) < self.max_num: #无空闲线程和不超过最大线程数
                self.generate_thread() # 创建线程
            w = (func, args, callback,)#保存参数为元组
            self.q.put(w)#添加到任务队列
    
        def generate_thread(self):
            """
            创建一个线程
            """
            t = threading.Thread(target=self.call)
            t.start()
    
        def call(self):
            """
            循环去获取任务函数并执行任务函数
            """
            current_thread = threading.currentThread#获取当前线程对象
            self.generate_list.append(current_thread)#添加到已创建线程里
            event = self.q.get() #获取任务
            while event != StopEvent: #如果不为停止信号
                func, arguments, callback = event#分别取值,
                try:
                    result = func(*arguments) #运行函数,把结果赋值给result
                    status = True   #运行结果是否正常
                except Exception as e:
                    status = False #不正常
                    result = e  #结果为错误信息
    
                if callback is not None: # 是否有回调函数
                    try:
                        callback(status, result) #执行回调函数
                    except Exception as e:
                        pass
    
                if self.terminal: # 默认为False ,如果调用terminal方法
                    event = StopEvent #停止信号
                else:
                    # self.free_list.append(current_thread) #执行完毕任务,添加到闲置列表
                    # event = self.q.get()    #获取任务
                    # self.free_list.remove(current_thread) #获取到任务之后,从闲置里删除
                    with self.worker_state(self.free_list,current_thread):
                        event = self.q.get()
            else:
                self.generate_list.remove(current_thread) #如果收到终止信号,就从已创建的列表删除
    
        def close(self): #终止线程
            num = len(self.generate_list) #获取总已创建的线程
            while num:
                self.q.put(StopEvent) #添加停止信号,有几个线程就添加几个
                num -= 1
    
        # 终止线程(清空队列)
        def terminate(self):
            self.terminal = True #更改为True,
    
            while self.generate_list: #如果有已创建线程存活
                self.q.put(StopEvent) #有几个就发几个信号
            self.q.empty()  #清空队列
            
        @contextlib.contextmanager
        def worker_state(self,free_list,current_thread):
            free_list.append(current_thread)
            try:
                yield
            finally:
                free_list.remove(current_thread)
    
    import time
    import random
    def work(i):
        sleep_sec=random.randint(1,3)
        print(threading.current_thread().name+ '  '+str(i)+'  '+str(sleep_sec))
        time.sleep(sleep_sec)
    
    pool = ThreadPool(3)
    for item in range(7):
        pool.run(func=work, args=(item,))
    # pool.terminate()
    pool.close()
    
    

    运行结果:
    在这里插入图片描述
    以上内容是我的个人总结,如有疑问,欢迎私聊,谢谢!!

    展开全文
  • Python线程池+任务队列

    2020-08-30 00:26:37
    一个基于thread和queue的线程池,以任务为队列元素,动态创建线程,重复利用线程, 通过close和terminate方法关闭线程池。 """ import queue import threading import contextlib import time # 创建空对象,用于...
  • Python线程池与进程池

    2020-07-04 13:25:26
    Python线程池与进程池 前言 很多人学习python,不知道从何学起。 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。 很多已经做案例的人,却不知道如何去学习更加高深的知识。 那么针对这三类人...
  • 文章目录背景方案设计ThreadPool类使用方法简单设计一个会抛...选择的线程池为multiprocessing.pool.ThreadPool。 方案设计 ThreadPool类使用方法 from multiprocesing.pool import ThreadPool # 创建一个线程池 poo
  • 在去年的一篇Python 多线程编程中学习了 Python 中如何使用多线程来调度任务,工作中也不时从自己的博客中找来参考。在运用当中不时的碰到内存消耗殆尽情况,直接把命令行窗口打死,不得不强行关窗口或杀进程。之前...
  • Python线程池及使用

    2020-02-13 22:06:06
    Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程,而同时只允许3个线程在...
  • 工作线程(worker):创建线程池时,按照指定的线程数量,创建工作线程,等待从任务队列中get任务; 任务(requests):即工作线程处理的任务,任务可能成千上万个,但是工作线程只有少数。任务通过 makeRequests来...
  • Python线程池实现

    2019-03-16 01:08:17
    NULL 博文链接:https://biansutao.iteye.com/blog/377402
  • 例一 # 首先导包 from concurrent.futures import ...# 创建线程池 executor = ThreadPoolExecutor(10) # 测试方法 def test_function(num1, num2): print(num1, num2) return num1 + num2 # 第一...
  • python线程池中的线程,如果在运行过程中如果遇到异常,是卡死然后线程池中的线程减少一,还是卡死后,线程池中的再填充一个新的线程.又或者是其他情况? 代码验证 代码如下: from concurrent.futures import ...
  • python线程池

    2020-12-09 21:27:37
    线程池 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import time def task(n): print("asas") time.sleep(2) return n*n def call_back(n): print("xxxx") print(n) if __name__ =...
  • python 线程池

    2020-10-21 11:06:22
    import random import threading import time def test(value1): time.sleep(random.randint(1, 5)) print("threading %s : %s"%(threading.current_thread().name, value1)) return ' %s finished' % value1 ...
  • 最近项目中需要抽取数据库中某些数据组成一个缓存表,SQL倒是不复杂就是单纯的慢,慢到navicat跑崩了也没跑出来,然后就想着用python写脚本,根据时间字段做异步查询 代码 数据库连接写成伪码,过程抽象一下就是...
  • python线程池+协程

    2021-01-19 00:04:52
    线程池 Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会...
  • Python 线程池原理及实现

    万次阅读 多人点赞 2017-07-26 18:08:38
    初始化一个4个线程的线程池,都阻塞等待这读取队列queue的任务 当socket.accept()有请求,则把conn_socket做为参数,handle_request方法,丢给线程池,等待线程池分配线程处理 GIL 对多线程的影响 因为Python的线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,075
精华内容 12,030
关键字:

python线程池

python 订阅