1、多线程、多进程

a、基础定义

进程:

一个程序,是一组资源的集合。

一个进程里边有一个默认线程,即主线程。

多进程可以利用多核CPU。

线程:

线程是最小的执行单位。

线程和线程之间是相互独立,但可以共享数据。

主线程会等待子线程执行结束。

※Python的多线程为伪多线程,无法有限利用多核CPU。实际上只能利用单核。

原因为全局解释器锁:GIL

b、创建线程

创建线程需声明import threading,该模块为Python自带,无需下载。

之后使用threading.Thread(target=XX)来定义子线程,其中XX为方法名。即使用新线程调用执行XX方法。

最后使用.start()方法来调用线程。

importthreadingimporttimedefclean():print('打扫卫生')

time.sleep(2)defxiyifu():print('洗衣服')

time.sleep(3)defcook():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 inthread_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)方法来设置守护线程,当主线程执行完毕后,子线程即自动结束。

python 如果创建多个线程一个一个执行相互等待 python可以创建多少个线程_主线程

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

importqueueimportrandomimporttimeimportthreading

orders_q=queue.Queue()#生产者/消费者模式

defproducer():for i in range(100):

order_id= random.randint(1, 99999)print('订单生成,orderid:%s'%order_id)

orders_q.put(order_id)

time.sleep(1)defconsumer():whileTrue: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个任务