一、进程池与线程池介绍

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

当并发的任务数远远超过了计算机的承受能力时,即无法一次性开启过多的进程数或线程数时
就应该用池的概念将开启的进程数或线程数 池子内什么时候装进程:并发的任务属于计算密集型
池子内什么时候装线程:并发的任务属于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的数目*5
6.如果是进程池,得到的结果如果是一个对象。我们得用一个.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函数应用

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

  1. python系列之 - 并发编程(进程池,线程池,协程)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  2. python并发编程之进程池,线程池,协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  3. python自带的进程池及线程池

    进程池 """ python自带的进程池 """ from multiprocessing import Pool from time im ...

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

    进程池与线程池 在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多, 这会对 ...

  5. Python并发编程之进程池与线程池

    一.进程池与线程池 python标准模块concurrent.futures(并发未来) 1.concurrent.futures模块是用来创建并行的任务,提供了更高级别的接口,为了异步执行调用 2. ...

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

    一:进程池与线程池 提交任务的两种方式: 1.同步调用:提交完一个任务之后,就在原地等待,等任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行 2.异步调用:提交完一个任务之后, ...

  7. python 36 进程池、线程池

    目录 1. 死锁与递归锁 2. 信号量Semaphor 3. GIL全局解释器锁:(Cpython) 4. IO.计算密集型对比 4.1 计算密集型: 4.2 IO密集型 5. GIL与Lock锁的区 ...

  8. python进程池与线程池

    为什么会进行池化? 一切都是为了效率,每次开启进程都会分配一个属于这个进程独立的内存空间,开启进程过多会占用大量内存,系统调度也会很慢,我们不能无限的开启进程. 进程池原来大概如下图 假设有100个任 ...

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

    9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于I ...

随机推荐

  1. 【Excel】单元格的下拉框是怎么做的?

    如果我们希望将产品这一列的每个单元格都能选择 左侧的产品就好了,就像这样 这里使用的是"验证数据有效性"功能 在这里: 点击F,选择F列后,打开“数据验证”,如图,选择序列,选择来 ...

  2. 手写HASHMAP

    手写HASHMAP const int MAXN=10010; const int HASH=10100;            //需要hash的数的总个数最大值 struct HASHMAP { ...

  3. 【转载】Spring最佳后台框架

    https://www.quora.com/What-is-the-best-backend-arquitecture-using-spring-framework The most modern a ...

  4. js面向对象理解

    js面向对象理解 ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是, ...

  5. 将本地已有项目上传到github

    1.在github上创建一个文件 2.看本地C盘中是否有.ssh文件夹 (C:\Users\用户名\.ssh) 检测有没有.ssh文件夹:执行命令   cd ~/.ssh 如果没有的话执行git命令: ...

  6. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  7. MySql+Memcached架构的问题

    Memcached采用客户端-服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端Library可以用任何语言实现. Memcached服务器使用基于Slab的内存管 ...

  8. 【CF163E 】e-Government

    题目 两个\(log\)的树状数组套树剖? 我们对于给出的\(n\)个模式串建立\(AC\)自动机,之后对于每一个询问串直接丢上去匹配 如果这里是暴力的话,我们直接一路跳\(fail\)累加作为结束位 ...

  9. 20155314 2016-2017-2 《Java程序设计》第9周学习总结

    20155314 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛型和自定义 ...

  10. Python的多线程和多进程

    (1)多线程的产生并不是因为发明了多核CPU甚至现在有多个CPU+多核的硬件,也不是因为多线程CPU运行效率比单线程高.单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进 ...