1,队列:填值,取值
put,get
from multiprocessing import Queue
q = Queue(3) #不填默认
q.put(1)
q.put(2)
q.put(3)
# q.put(4) #Full ,填不了值,会一直阻塞
print(q.get())
print(q.get())
print(q.get())
# print(q.get()) #取不了值,会一直阻塞
# print(666) #
put_nowait,get_nowait
import queue
from multiprocessing import Queue
q = Queue(10)
num = 0
while True:
try:
q.put_nowait(num)
num += 1
except queue.Full:
print('填值完毕')
break
while True:
try:
print(q.get_nowait())
except queue.Empty:
print('取值完毕')
break
2.生产者消费模型:
import time
import random
from multiprocessing import Process,Queue
def customer(q,name):
while True:
f = q.get()
print(f)
if f is None:
break
time.sleep(random.uniform(0.5,0.7))
print('%s吃了%s'%(name,f))
def producer(q,name,food):
for i in range(10):
time.sleep(random.uniform(0.1,0.5))
print('%s生产了%s%s' % (name,i,food))
q.put(str(i)+food)
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer,args=(q,'狗子','骨头'))
p1.start()
p = Process(target=customer,args=(q,'小狗'))
p.start()
p1.join()
q.put(None)
3:进程池:开启过多的进程并不能提高效率,反而会降低效率.
过多的进程,会造成阻塞,占用内存,操作系统需要对这些进程分配到各个CPU中进行处理
计算机两种类型:
计算型:会充分占用CPU:写的程序是计算型程序,适合使用,多进程可以充分利用多核
适合开启多进程,不适合开启超过CPU数量过多的进程
IO型:大部分在阻塞队列里,而不是在运行状态中:大部分时间在等待(如爬虫,文件操作)
不适合开启多进程
import time
from multiprocessing import Process,Pool
def func(i):
time.sleep(0.1)
print('第%s件衣服制作完毕'%i)
if __name__ == '__main__':
p1 = Pool(8) #开启多进程,关闭的时候,一次性全关闭:多进程,高计算,少阻塞时使用
start = time.time()
for i in range(1000):
p1.apply_async(func,args=(i,))
p1.close()
p1.join()
print(time.time() - start)
# p2 = Process()#开启一个进程,执行完毕后关闭一个
# p_lst = []
# start = time.time()
# for i in range(1000):
# p2 = Process(target=func,args=(i,))
# p2.start()
# p_lst.append(p2)
# for p in p_lst:
# p2.join()
# print(time.time() - start)
进程池,同步提交
import time
import os
from multiprocessing import Pool
def task(num):
time.sleep(0.5)
print('%s:%s'%(num,os.getpid()))
if __name__ == '__main__':
p = Pool()
for i in range(40):
p.apply(task,args=(i,)) #提交任务的方法 : 同步提交
主进程与子进程的数据是隔离的,但是进程池的类实现了返回值 :ipc机制
import time
import os
from multiprocessing import Pool
def task(num):
time.sleep(0.5)
print('%s:%s'%(num,os.getpid()))
return num**2
if __name__ == '__main__':
p = Pool()
for i in range(40):
res = p.apply(task,args=(i,)) #提交任务的方法 : 同步提交
#apply同步提交,一个一个顺序执行,没有并发的效果
print(res) #主进程与子进程的数据是隔离的,但是进程池的类实现了返回值 :ipc机制
异步提交:apply_async
没有返回值的情况下
import time
import os
from multiprocessing import Pool
def task(num):
time.sleep(0.5)
print('%s:%s'%(num,os.getpid()))
return num**2
if __name__ == '__main__':
p = Pool(os.cpu_count()+1)
res_lst = []
for i in range(40):
res = p.apply_async(task,args=(i,)) #提交任务的方法 : 异步提交
# print(res) #主进程与子进程的数据是隔离的,但是进程池的类实现了返回值 :ipc机制
# res_lst.append(res)
# for res in res_lst:
# print(res.get())
p.close() #无法再提交,子进程继续执行
p.join()
有返回值,get不能再提交任务之后立刻执行,需要先提交所有的任务再通过get获取值
import time
import os
from multiprocessing import Pool
def task(num):
time.sleep(0.5)
print('%s:%s'%(num,os.getpid()))
return num**2
if __name__ == '__main__':
p = Pool(os.cpu_count()+1)
res_lst = []
for i in range(40):
res = p.apply_async(task,args=(i,)) #提交任务的方法 : 异步提交
res_lst.append(res)
for res in res_lst:
print(res.get())
进程池中的map()方法,
异步提交的简化版本,
自带close 和join方法
不带返回值,要带可以把返回值先放到队列中,再get获取
import time
import os
from multiprocessing import Pool
def task(num):
time.sleep(0.5)
print('%s:%s'%(num,os.getpid()))
return num**2
if __name__ == '__main__':
p = Pool()
p.map(task,range(20))