python之进程池与线程池

一、进程池与线程池介绍池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务

当并发的任务数远远超过了计算机的承受能力时,即无法一次性开启过多的进程数或线程数时就应该用池的概念将开启的进程数或线程数

池子内什么时候装进程:并发的任务属于计算密集型池子内什么时候装线程:并发的任务属于IO密集型
不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池。其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉

只要你用并发,就会有锁的问题,但是你不能一直去自己加锁吧那么我们就用QUEUE,这样还解决了自动加锁的问题由Queue延伸出的一个点也非常重要的概念。以后写程序也会用到这个思想。就是生产者与消费者问题

一、Python标准模块--concurrent.futures(并发未来)

concurent.future模块需要了解的1.concurent.future模块是用来创建并行的任务,提供了更高级别的接口,为了异步执行调用2.concurent.future这个模块用起来非常方便,它的接口也封装的非常简单3.concurent.future模块既可以实现进程池,也可以实现线程池4.模块导入进程池和线程池from  concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor还可以导入一个Executor,但是你别这样导,这个类是一个抽象类抽象类的目的是规范他的子类必须有某种方法(并且抽象类的方法必须实现),但是抽象类不能被实例化5.  p = ProcessPoolExecutor(max_works)对于进程池如果不写max_works:默认的是cpu的数目,默认是4个  p = ThreadPoolExecutor(max_works)对于线程池如果不写max_works:默认的是cpu的数目*56.如果是进程池,得到的结果如果是一个对象。我们得用一个.get()方法得到结果  但是现在用了concurent.future模块,我们可以用obj.result方法  p.submit(task,i)  #相当于apply_async异步方法  p.shutdown()  #默认有个参数wite=True (相当于close和join)

那么什么是线程池呢?我们来了解一下

二、线程池

进程池:就是在一个进程内控制一定个数的线程基于concurent.future模块的进程池和线程池 (他们的同步执行和异步执行是一样的)

 1 # 1.同步执行--------------
 2 from  concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
 3 import os,time,random
 4 def task(n):
 5     print(‘[%s] is running‘%os.getpid())
 6     time.sleep(random.randint(1,3))  #I/O密集型的,,一般用线程,用了进程耗时长
 7     return n**2
 8 if __name__ == ‘__main__‘:
 9     start = time.time()
10     p = ProcessPoolExecutor()
11     for i in range(10): #现在是开了10个任务, 那么如果是上百个任务呢,就不能无线的开进程,那么就得考虑控制
12         # 线程数了,那么就得考虑到池了
13         obj  = p.submit(task,i).result()  #相当于apply同步方法
14     p.shutdown()  #相当于close和join方法
15     print(‘=‘*30)
16     print(time.time() - start)  #17.36499309539795
17
18
19 # 2.异步执行-----------
20 # from  concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
21 # import os,time,random
22 # def task(n):
23 #     print(‘[%s] is running‘%os.getpid())
24 #     time.sleep(random.randint(1,3))  #I/O密集型的,,一般用线程,用了进程耗时长
25 #     return n**2
26 # if __name__ == ‘__main__‘:
27 #     start = time.time()
28 #     p = ProcessPoolExecutor()
29 #     l = []
30 #     for i in range(10): #现在是开了10个任务, 那么如果是上百个任务呢,就不能无线的开进程,那么就得考虑控制
31 #         # 线程数了,那么就得考虑到池了
32 #         obj  = p.submit(task,i)  #相当于apply_async()异步方法
33 #         l.append(obj)
34 #     p.shutdown()  #相当于close和join方法
35 #     print(‘=‘*30)
36 #     print([obj.result() for obj in l])
37 #     print(time.time() - start)  #5.362306594848633

基于concurrent.futures模块的进程池

 1 from  concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
 2 from threading import currentThread
 3 import os,time,random
 4 def task(n):
 5     print(‘%s:%s is running‘%(currentThread().getName(),os.getpid()))  #看到的pid都是一样的,因为线程是共享了一个进程
 6     time.sleep(random.randint(1,3))  #I/O密集型的,,一般用线程,用了进程耗时长
 7     return n**2
 8 if __name__ == ‘__main__‘:
 9     start = time.time()
10     p = ThreadPoolExecutor() #线程池 #如果不给定值,默认cup*5
11     l = []
12     for i in range(10):  #10个任务 # 线程池效率高了
13         obj  = p.submit(task,i)  #相当于apply_async异步方法
14         l.append(obj)
15     p.shutdown()  #默认有个参数wite=True (相当于close和join)
16     print(‘=‘*30)
17     print([obj.result() for obj in l])
18     print(time.time() - start)  #3.001171827316284

基于concurrent.futures模块的线程池

应用线程池(下载网页并解析)

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import requests
import time,os
def get_page(url):
    print(‘<%s> is getting [%s]‘%(os.getpid(),url))
    response = requests.get(url)
    if response.status_code==200:  #200代表状态:下载成功了
        return {‘url‘:url,‘text‘:response.text}
def parse_page(res):
    res = res.result()
    print(‘<%s> is getting [%s]‘%(os.getpid(),res[‘url‘]))
    with open(‘db.txt‘,‘a‘) as f:
        parse_res = ‘url:%s size:%s\n‘%(res[‘url‘],len(res[‘text‘]))
        f.write(parse_res)
if __name__ == ‘__main__‘:
    # p = ThreadPoolExecutor()
    p = ProcessPoolExecutor()
    l = [
        ‘http://www.baidu.com‘,
        ‘http://www.baidu.com‘,
        ‘http://www.baidu.com‘,
        ‘http://www.baidu.com‘,
    ]
    for url in l:
        res = p.submit(get_page,url).add_done_callback(parse_page) #这里的回调函数拿到的是一个对象。得
        #  先把返回的res得到一个结果。即在前面加上一个res.result() #谁好了谁去掉回调函数
                                # 回调函数也是一种编程思想。不仅开线程池用,开线程池也用
    p.shutdown()  #相当于进程池里的close和join
    print(‘主‘,os.getpid())

map函数的应用

# map函数举例
obj= map(lambda x:x**2 ,range(10))
print(list(obj))

#运行结果[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

可以和上面的开进程池/线程池的对比着看,就能发现map函数的强大了

 1 # 我们的那个p.submit(task,i)和map函数的原理类似。我们就
 2 # 可以用map函数去代替。更减缩了代码
 3 from  concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
 4 import os,time,random
 5 def task(n):
 6     print(‘[%s] is running‘%os.getpid())
 7     time.sleep(random.randint(1,3))  #I/O密集型的,,一般用线程,用了进程耗时长
 8     return n**2
 9 if __name__ == ‘__main__‘:
10     p = ProcessPoolExecutor()
11     obj = p.map(task,range(10))
12     p.shutdown()  #相当于close和join方法
13     print(‘=‘*30)
14     print(obj)  #返回的是一个迭代器
15     print(list(obj))

map函数应用

原文地址:https://www.cnblogs.com/sui776265233/p/9329046.html

时间: 2024-11-05 14:51:22

python之进程池与线程池的相关文章

4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞

一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点:  保证Cpython解释器内存管理的线程安全 缺点:同一进程内所有的线程同一时刻只能有一个执行,也就说Cpython解释器的多线程无法实现并行 二.GIL与多线程 有了GIL的存在,同一时刻同一进程中只有一个线程被执行 听到这里,有的同学立马质问:进程可以利用多核,但是开销大,而python的多线程开销

python并发编程之进程池,线程池concurrent.futures

进程池与线程池 在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多, 这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪,于是我们必须对服务端开启的进程数或线程数加以控制,让机器在一个自己可以承受的范围内运行,这就是进程池或线程池的用途, 例如进程池,就是用来存放进程的池子,本质还是基于多进程,只不过是对开启进程的数目加上了限制 Python--concurrent.fu

python并发编程之进程池,线程池

要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉只要你用并发,就会有锁的问题,但是你不能一直去自己加锁吧那么我们就用QUEUE,这样还解决了自动加锁的问题由Queue延伸出的一个点也非常重要的概念.以后写程序也会用到这个思想.就是生产者与消费者问题 一.Python标准模块--concurrent.futures(并发未来) concurent.future模块需要了解的1.concurent.fut

python 之 并发编程(进程池与线程池、同步异步阻塞非阻塞、线程queue)

9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于IO密集型 进程池: from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time,os,random ? def task(x): print('%s 接客' %os.getpid()) time.

python全栈脱产第37天------进程池与线程池、协程、gevent模块、单线程下实现并发的套接字通信

一.进程池与线程池 调用concurrent.futures下的ThreadPoolExecutor,ProcessPoolExecutor来实现 提交任务有两种方式:同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,在执行下一段代码,是串行的 异步调用:提交完一个任务之后,不在原地等待,直接运行下一段代码,任务是并发的 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutorimp

Python 37 进程池与线程池 、 协程

一:进程池与线程池 提交任务的两种方式: 1.同步调用:提交完一个任务之后,就在原地等待,等任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行 2.异步调用:提交完一个任务之后,不是原地等待,而是直接执行下一行代码,会导致任务是并发执行的,结果future对象会在任务运行完毕后自动传给回调函数 二:协程 基于单线程下实现并发,只有一个主线程(如下图:可利用的CPU只有一个)的情况下实现并发,并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下自习其他任务(切换

使用concurrent.futures模块并发,实现进程池、线程池

一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的异步多线程/多进程代码.从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类ThreadPoolExecutor和ProcessPoolExecutor继承了Executor,分别被用来创建线程池和进程池的代码.实现了对thread

27 Apr 18 GIL 多进程多线程使用场景 线程互斥锁与GIL对比 基于多线程实现并发的套接字通信 进程池与线程池 同步、异步、阻塞、非阻塞

27 Apr 18 一.全局解释器锁 (GIL) 运行test.py的流程: a.将python解释器的代码从硬盘读入内存 b.将test.py的代码从硬盘读入内存  (一个进程内装有两份代码) c.将test.py中的代码像字符串一样读入python解释器中解析执行 1 .GIL:全局解释器锁 (CPython解释器的特性) In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple na

Python入门学习-DAY37-进程池与线程池、协程、gevent模块

一.进程池与线程池 基本使用: 进程池和线程池操作一样 提交任务的两种方式: 同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的 异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的 同步调用 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time,random,os