自动化-day9-Python基础(多线程、多进程、单元测试)
1、多线程、多进程
a、基础定义
进程:
一个程序,是一组资源的集合。
一个进程里边有一个默认线程,即主线程。
多进程可以利用多核CPU。
线程:
线程是最小的执行单位。
线程和线程之间是相互独立,但可以共享数据。
主线程会等待子线程执行结束。
※Python的多线程为伪多线程,无法有限利用多核CPU。实际上只能利用单核。
原因为全局解释器锁:GIL
b、创建线程
创建线程需声明import threading,该模块为Python自带,无需下载。
之后使用threading.Thread(target=XX)来定义子线程,其中XX为方法名。即使用新线程调用执行XX方法。
最后使用.start()方法来调用线程。
import threading import time def clean(): print('打扫卫生') time.sleep(2) def xiyifu(): print('洗衣服') time.sleep(3) def cook(): print('做饭') time.sleep(1) start_time = time.time() t = threading.Thread(target=clean) #创建子线程 t2 = threading.Thread(target=xiyifu) t3 = threading.Thread(target=cook) t.start()#运行子线程 t2.start() t3.start()
c、确认线程执行完毕
i、使用.join()方法来等待进程执行完毕(正常退出或者抛出未处理的异常)。
※多线程时可以将线程append进list中,再for循环调用join方法确认线程执行完毕。
ii、通过判断当前存活的线程数来判断线程是否执行完毕。
※线程执行完毕后会自动释放线程资源,因此当多线程执行完毕后,当前存活线程将只剩下一个主线程。
※即可以使用threading.active_count()方法来取得当前存活线程数,当该数字为1时,即线程执行完毕。
# 1、等待多个子线程执行结束,把启动的子线程放到list中,在循环调用t.join thread_list = [] for i in range(10): t = threading.Thread(target=export_data) thread_list.append(t) t.start() for t in thread_list: t.join() print('数据都导完了') # 2、等待多个子线程执行结束,通过判断当前线程数 for i in range(10): t = threading.Thread(target=export_data,args=['db1','a.xls']) t.start() while threading.active_count() != 1: pass print(result_list) print('数据都导完了')
d、守护线程
守护线程依赖于主线程,当主线程执行完毕后,无论子线程是否执行完成,都将自动结束线程。
在创建线程时使用.setDaemon(True)方法来设置守护线程,当主线程执行完毕后,子线程即自动结束。

e、锁
多个线程在操作同一个变量时,需要加锁操作,避免导致数据异常,在操作完毕后再进行解锁。
可以使用lock.acquire()和lock.release()方法来操作加、解锁。
也可以使用with lock:的方式,当该代码块执行时会自动加锁,执行完毕后会自动解锁。
※加、解锁务必一一对应,避免造成进程死锁
f、线程池、队列
需要安装threadpool模块
队列用于暂时存储数据,先进先出,队列在数据取出后即销毁该数据。主要用于异步化处理,且可以保证数据顺序。
使用队列时,需声明queue模块,然后orders_q = queue.Queue()实例化一个队列。
之后使用orders_q.put(order_id)方法来插入数据,以及oreder_id = orders_q.get()方法取出数据
#队列 list import queue import random import time import threading orders_q = queue.Queue() #生产者/消费者模式 def producer(): for i in range(100): order_id = random.randint(1, 99999) print('订单生成,orderid:%s'%order_id) orders_q.put(order_id) time.sleep(1) def consumer(): while True: if orders_q.qsize()>0: oreder_id = orders_q.get() print('consumer1,订单落库',oreder_id) t = threading.Thread(target=producer) t.start() t = threading.Thread(target=consumer) t.start()
2.09.30多线程
1、多线程、多进程
cpu密集型任务:
消耗cpu比较多
排序、运算。。
io密集型任务
input/output
写文件、读文件
上传、下载
队列
1、异步处理
2、保证顺序
并发:
100
8 c 同时最多只能运行8个任务

浙公网安备 33010602011771号