Python进程、线程
python进程、线程、协程的关系图
Python进程、线程的区别
·一个进程产生多个线程
·线程是共享内存的,进程是独立的
·线程多数为进程服务的不能单独运行
Python线程
Python线程方法
start 线程准备就绪等待CPU调度
setName 为线程设置名称
getName 获取线程名称
SetDaemon 设置为后台线程或前台线程(默认)
如果是后台线程,主线程执行过程中,后台线程也在执行,主线程执行完毕后,后台线程不论成功与否,均停止
如果是前台进程,主线程执行过程中,前台进程也在执行,主线程执行完毕后,等待前台进程也执行完毕后,程序停止
join 逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程无意义
run 线程呗CPU调度后自动执行线程对象的run方法
Pyhton多线程和单线程对比
模块:threading
import threading import time #################不使用多线程############ #如果不使用多线程,只执行两边f1函数 需要两秒 def f1(arg): time.sleep(1) #停一秒 print(arg) f1(1) f1(2) ##############使用多线程################ #如果使用多线程,会同时执行函数,需要一秒 t1 = threading.Thread(target=f1,args=(1,)) #这个是线程 t1.start() t2 = threading.Thread(target=f1,args=(2,)) t2.start()
Python线程锁
模块:threading.RLock
作用:由于线程之间是随机调度,当多个线程同时修改同一条数据时可能会出现脏数据,所以出现的线程锁,同一时刻只允许一个线程执行操作
import threading import time NUM = 10 def func(l): global NUM l.acquire() #上锁,在这里阻塞了10个线程,因为下面创建了10个线程,线程是同时执行的,所以在这里上一个锁,同一时段只能一个线程执行. NUM -=1 time.sleep(2) print(NUM) l.release() #解锁 lock = threading.RLock() for i in range(10): t = threading.Thread(target=func,args=(lock,)) t.start()
Python生产者消费者模型
概念图:
概念:
在P3版本升级项目中,信息服务器要接收大批量的客户端请求,原来那种串行化的 处理,根本无法及时处理客户端请求,造成信息服务器大量请求堆积,导致丢包异 常严重.之后就采用了生产者消费者模式,在业务请求与业务处理间,建立了一个List 类型的缓冲区,服务端接收到业务请求,就往里扔,然后再去接收下一个业务请求,而 多个业务处理线程,就会去缓冲区里取业务请求处理.这样就大大提高了服务器的相应速度
代码: import threading import time import random import queue #队列模块 def Producer(name,que): #生产者 while True: que.put(‘包子‘) #相当于把包子放到仓库里 print(‘%s:做了一个包子‘ %name) #打印出做了一个包子出来 time.sleep(random.randrange(5)) #厨师5秒内做出一个包子 def Consumer(name,que): #消费者 while True: try: #异常处理,如果碰到没有包子可吃就等待厨师做包子 que.get_nowait() print(‘%s:吃了一个包子‘ %name) except Exception: print(u‘没有包子了‘) time.sleep(random.randrange(3)) #消费者3秒内吃掉一个包子 q = queue.Queue() #队列 p1 = threading.Thread(target=Producer,args=[‘厨师1‘,q]) #目标是Producer这个函数,args是传参 p2 = threading.Thread(target=Producer,args=[‘厨师2‘,q]) p1.start() p2.start() c1 = threading.Thread(target=Consumer,args=[‘张三‘,q]) c2 = threading.Thread(target=Consumer,args=[‘李四‘,q]) c1.start() c2.start() 结果: 厨师1:做了一个包子 厨师2:做了一个包子 张三:吃了一个包子 李四:吃了一个包子 没有包子了 没有包子了 厨师1:做了一个包子 李四:吃了一个包子 没有包子了 没有包子了
Python线程间通信
模块:threading.event
作用:Python提供了event对象用于线程间通信,它是由线程设置的信号标志,如果信号标志为真,则其他线程等待直到信号结束
流程:
1:设置信号
使用event的set()方法可以设置event对象内部的信号标志为真,event对象提供了isSet()方法判断其内部信号标志的状态.当使用event对象的set()方法后,isSet()方法返回真
2:清除信号
使用event的clear()方法可以清除event对象内部的信号标志,即将其设置为假,当使用event的clear()方法后,isSet()方法返回假
3:等待
使用event的wait()方法只有在内部信号为真的时候才会很快的执行并完成返回.当event对象的内部信号标志位为假时,则wait()方法一直等待带为真时才返回
代码: import threading import time def prodecer(): print(‘厨师:等人来买包子‘) #先打印这句 event.wait() #打印完上一句就等待consumer线程把False变成True event.clear() #然后清除状态 print(‘厨师:有人来买包子了‘) #如果consumer把False变成True,就打印这一句 print(‘厨师:我在给你做包子‘) #在打印这一句 time.sleep(5) #停5秒钟 print(‘厨师:包子好了,来拿吧‘) #打印这一句的时候把False变成True,告诉另一个线程 event.set() def consumer(): print(‘张三:去买个包子吃‘) event.set() #把False变成True告诉producer线程 time.sleep(2) print(‘张三:等着包子做好‘) while True: if event.isSet(): print(‘thanks‘) break else: print(‘张三:好了吗‘) time.sleep(1) 结果: 厨师:等人来买包子 张三:去买个包子吃 厨师:有人来买包子了 厨师:我在给你做包子 张三:等着包子做好 张三:好了吗 张三:好了吗 张三:好了吗 张三:好了吗 厨师:包子好了,来拿吧 thanks
原文:http://www.cnblogs.com/zhaijunming5/p/5697651.html