1.进程间通信-Queue
创建消息队列
queue = multiprocessing.Queue(5)
在消息队列里写数据
queue.put(x)
从消息队列里读数据
queue.get()
实例:
import multiprocessing # 任务1 def write(queue): for i in range(10): # 判断容量是否满了 if queue.full(): print("满了") break print("write:", i) queue.put(i) # 任务2 def read(queue): for i in range(10): # 判断如果容量空了 if queue.empty(): print("空了") break print("read:", queue.get()) if __name__ == '__main__': # 创建消息队列 # 注意 在linux系统可以写在上面 但是windows是不可以的 queue = multiprocessing.Queue(5) # 创建进程 -> 新建状态 write_process = multiprocessing.Process(target=write, args=(queue,)) read_process = multiprocessing.Process(target=read, args=(queue,)) # 启动进程 就绪状态 write_process.start() # 进程同步 write_process.join() read_process.start()
进程池pool
创建进程池
import multiprocessing
pool = multiprocessing.Pool(设置进程数量)
使用进程池中的进程执行任务
for i in range(10): pool.apply_async(任务名) # 固定用法(在主进程等待前 需要关闭进程池 不再接收新的任务) pool.close() # 保证主进程堵塞(等待) pool.join()
迭代;可以使用for循环完成循环遍历的对象 我们称之为可迭代对象
如何判断一个对象是否是可迭代对象(查看一个对象的数据类型)
from collections import Iterable
flag = isinstance(判断对象, Iterable)
print(flag)
生成器,用yield返回我们称之为生成器,生成器是特殊的迭代器
生成器的三种启动方式
# 创建一个生成器对象
fib = Fibonacci(5)
01.fib.send(None)(第一次必须是None,之后可以是一个数值)
02.next(fib)
03.fib.__next__()
使用生成器完成斐波那契数列
def Fibonacci(num): a = 0 b = 1 current_index = 0 while current_index < num: current_index += 1 result = a a, b = b, a + b ret = yield result print(ret) if __name__ == '__main__': # 创建一个生成器对象 fib = Fibonacci(5) # 启动生成器 #如果使用send启动生成器 第一次必须传入一个None # print(fib.send(None)) # print(next(fib)) # print(fib.send(123)) # print(fib.__next__())
协程,称之为微进程,是一个特殊的生成器
简单实例:
import time #任务1 def work1(): while True: print("work1....") yield time.sleep(0.1) #任务2 def work2(): while True: print("work2....") yield time.sleep(0.1) if __name__ == '__main__': # 创建协程 g1 = work1() g2 = work2() while True: next(g1) next(g2)
greenlet:
import greenlet
用greenlet创建协程
协程名 = greenlet.greenlet(要执行的函数名)
例:
import greenlet, time #任务1 def work1(): while True: print("work1....") # 切换到另一个协程执行任务 g2.switch() time.sleep(0.1) #任务2 def work2(): while True: print("work2....") # 切换到另一个协程执行任务 g1.switch() time.sleep(0.1) if __name__ == '__main__': # 创建了两个协程执行任务 g1 = greenlet.greenlet(work1) g2 = greenlet.greenlet(work2) # 启动协程 g1.switch()
gevent的使用
例:
import gevent, time from gevent import monkey # 打补丁(gevent才知道哪些是耗时操作) monkey.patch_all() # 任务1 def work1(): for i in range(15): print("work1...") time.sleep(0.1) # 任务2 def work2(): for i in range(15): print("work2...") time.sleep(0.1) if __name__ == '__main__': # gevent特点 是在执行一个耗时操作后才会交替执行 # 创建协程 g1 = gevent.spawn(work1) g2 = gevent.spawn(work2) # 主线程等待 g1.join() g2.join()
利用gevent下载多张图片
# jionall 不需要再每次调用join gevent.joinall([ gevent.spawn(load_img, img_url1, "1.jpg"), gevent.spawn(load_img, img_url2, "2.jpg"), gevent.spawn(load_img, img_url3, "3.jpg") ])