zoukankan      html  css  js  c++  java
  • 进程池 线程池 同步异步 阻塞非阻塞

    什么是进程/线程池

        池本身表示一个容器,本质上就是一个存储进程或线程的列表

    池中该储存线程还是进程

        如果是IO密集型任务使用线程池,如果是计算密集型任务则使用进程池

    为什么需要进程或者线程池

        在很多情况下需要控制进程或线程的数量在一个合理的范围内,例如TCP程序中,一个客户端对应一个线程,虽然线程的开销小,但是肯定不能无限开,否则操作系统资源迟早被耗尽,解决的办法就是控制线程的数量。线程或进程池不仅帮助我们控制线程/进程的数量,还帮助我们完成了线程/进程的创建,销毁,以及任务的分配

    进程池的使用:

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    import time,os

    # 创建进程池,指定最大进程数为3,此时不会创建进程,不指定数量时,默认为CPU和核数
    pool = ProcessPoolExecutor(3)

    def task():
    time.sleep(1)
    print(os.getpid(),"working..")

    if __name__ == '__main__':
    for i in range(10):
    pool.submit(task) # 提交任务时立即创建进程

    # 任务执行完成后也不会立即销毁进程
    time.sleep(2)

    for i in range(10):
    pool.submit(task) #再有新任务是 直接使用之前已经创建好的进程来执行

    线程的使用

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    from threading import current_thread,active_count
    import time,os

    # 创建进程池,指定最大线程数为3,此时不会创建线程,不指定数量时,默认为CPU和核数*5
    pool = ThreadPoolExecutor(3)
    print(active_count()) # 只有一个主线

    def task():
    time.sleep(1)
    print(current_thread().name,"working..")

    if __name__ == '__main__':
    for i in range(10):
    pool.submit(task) # 第一次提交任务时立即创建线程

    # 任务执行完成后也不会立即销毁
    time.sleep(2)

    for i in range(10):
    pool.submit(task) #再有新任务时 直接使用之前已经创建好的线程来执行

    同步 异步 阻塞 非阻塞

    阻塞:当程序执行过程中遇到IO操作时,在执行io操作时,程序无法继续执行其他代码,称为阻塞。                                       非阻塞:程序在正常运行没有遇到IO操作,或者通过某种方式使程序即使遇到了也不会停在原地,还可以执行其他操作,以提高CPU的占用率。                                                                   

    同步和异步 指的是提交任务的方式                                            同步指调用:发起任务后必须在原地等待任务执行完成,才能继续执行                                 异步指调用:发起任务后必须不用等待执行任务,可以立即开启执行其他操作                                                                                  同步会有等待的效果但是这和阻塞是完全不同的,阻塞时程序会被剥夺CPU执行权,而同步调用则不会!
    异步的调用一

    from concurrent.futures import ThreadPoolExecutor
    from threading import current_thread
    import time

    pool = ThreadPoolExecutor(3)
    def task(i):
    time.sleep(0.01)
    print(current_thread().name,"working..")
    return i ** i

    if __name__ == '__main__':
    objs = []
    for i in range(3):
    res_obj = pool.submit(task,i) # 异步方式提交任务# 会返回一个对象用于表示任务结果
    objs.append(res_obj)

    # 该函数默认是阻塞的 会等待池子中所有任务执行结束后执行
    pool.shutdown(wait=True)

    # 从结果对象中取出执行结果
    for res_obj in objs:
    print(res_obj.result())
    print("over")

    异步的调用二

    import time

    pool = ThreadPoolExecutor(3)
    def task(i):
    time.sleep(0.01)
    print(current_thread().name,"working..")
    return i ** i

    if __name__ == '__main__':
    objs = []
    for i in range(3):
    res_obj = pool.submit(task,i) # 会返回一个对象用于表示任务结果
    print(res_obj.result()) #result是同步的一旦调用就必须等待 任务执行完成拿到结果
    print("over")

  • 相关阅读:
    【C#】3.算法温故而知新
    【C#】2.算法温故而知新
    【C#】1.算法温故而知新
    【C#】SQL数据库助手类2.0(自用)
    【Javascript Demo】JS获取当前对象大小以及屏幕分辨率等
    【Android 基础】Android中全屏或者取消标题栏
    【ASP.NET 问题】System.InvalidOperationException: 对象的当前状态使该操作无效 【大量表单数据提交】错误解决
    【CSS】颜色码对照表
    【Ext.Net学习笔记】07:后续
    【Ext.Net学习笔记】06:Ext.Net GridPanel的用法(GridPanel 折叠/展开行、GridPanel Selection、 可编辑的GridPanel)
  • 原文地址:https://www.cnblogs.com/tangda/p/10502330.html
Copyright © 2011-2022 走看看