需要注意一下
不能无限的开进程,不能无限的开线程
最常用的就是开进程池,开线程池。其中回调函数非常重要
回调函数其实可以作为一种编程思想,谁好了谁就去掉
只要你用并发,就会有锁的问题,但是你不能一直去自己加锁吧
那么我们就用QUEUE,这样还解决了自动加锁的问题
由Queue延伸出的一个点也非常重要的概念。以后写程序也会用到
这个思想。就是生产者与消费者问题
from multiprocessing importProcess,Poolimporttime,osdefFoo(i):
time.sleep(1)print(i)print("son",os.getpid())return "HELLO %s"%idefBar(arg):print(arg)#print("hello")
#print("Bar:",os.getpid())
if __name__ == '__main__':
pool= Pool(5)print("main pid",os.getpid())for i in range(100):#pool.apply(func=Foo, args=(i,)) #同步接口
#pool.apply_async(func=Foo, args=(i,))
#回调函数: 就是某个动作或者函数执行成功后再去执行的函数
pool.apply_async(func=Foo, args=(i,),callback=Bar)
pool.close()
pool.join()#join与close调用顺序是固定的
print('end')
j进程池
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
pool = ThreadPoolExecutor(10) # 线程池
# pool = ProcessPoolExecutor(10) # 进程池
for url in url_list:
pool.submit(func, args)
一、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.同步执行--------------
from concurrent.futures importProcessPoolExecutor,ThreadPoolExecutorimportos,time,randomdeftask(n):print('[%s] is running'%os.getpid())
time.sleep(random.randint(1,3)) #I/O密集型的,,一般用线程,用了进程耗时长
return n**2
if __name__ == '__main__':
start=time.time()
p=ProcessPoolExecutor()for i in range(10): #现在是开了10个任务, 那么如果是上百个任务呢,就不能无线的开进程,那么就得考虑控制
#线程数了,那么就得考虑到池了
obj = p.submit(task,i).result() #相当于apply同步方法
p.shutdown() #相当于close和join方法
print('='*30)print(time.time() - start) #17.36499309539795
#2.异步执行-----------#from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor#import os,time,random#def task(n):#print('[%s] is running'%os.getpid())#time.sleep(random.randint(1,3)) #I/O密集型的,,一般用线程,用了进程耗时长#return n**2#if __name__ == '__main__':#start = time.time()#p = ProcessPoolExecutor()#l = []#for i in range(10): #现在是开了10个任务, 那么如果是上百个任务呢,就不能无线的开进程,那么就得考虑控制## 线程数了,那么就得考虑到池了#obj = p.submit(task,i) #相当于apply_async()异步方法#l.append(obj)#p.shutdown() #相当于close和join方法#print('='*30)#print([obj.result() for obj in l])#print(time.time()