Python-开发之路-线程基础
2016-07-23 08:42
573 查看
引例:
举例:
生产者消费者模型(队列)生产者和消费者之间存在一个队列(作用在于解耦:解除程序间的耦合)
是否有队列存在的不同工作方式
相当于火车票的两种购买方式
第一种没有队列方式:
类比火车站售票口买票,同一时间的最大能处理任务的能力就是站在售票口的人,其他人需要排队。
缺点:占用资源、浪费时间、效率低下。
第二种有队列方式:
类比在12306上进行买票时,队列可以将更多的任务提前接收起来,然后独立的给后端窗口提供任务,那么这个队列的最大容量就是处理任务的最大负载。从经济学角度,12306其实卖的是期货,先把预授权卖给你,后台继续按照原有速度处理,不用大量排队,提交任务之后,就可以去干别的事了。
在此引入一个概念:队列,以规定好的读取顺序进行消息收集的一个集合
后进先出
优先级队列(设有权重)
双向队列
RLock
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 """ IO密集型:使用多线程 计算密集型:使用多进程 原因:1、python有个GIL 全局解释权锁;CPython有GIL,JPython没有GIL python,2.7按照寄存器中指令数分片,每个线程执行100条指令;3.5中以处理时间分片 ,每个线程执行时间也有限制 """ import time def f1(args): time.sleep(3) print(args) import threading t = threading.Thread(target=f1,args=(123,)) t.setDaemon(True) #默认为False,表示等子线程执行完,True表示不等带子线程 t.start() #不代表当前线程会被立即执行 t.join(2) #表示主线程到此等待,直到子线程执行完,参数表示最多等待n秒 f1(111) print('1') print('2')
基本使用
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 import threading ''' 以下为两种创建线程的方法 ''' #方法一:调用线程模块 def f1(arg): print(arg) t = threading.Thread(target=f1,args=(123,)) t.start() #方法二:自己写一个自定义的线程:借用构造函数提前设置 class Mythread(threading.Thread): def __init__(self,func,args): self.func = func self.args = args super(Mythread,self).__init__() def run(self): self.func(self.args) def f2(args): print(args) obj = Mythread(f2,123) obj.start()
举例:
生产者消费者模型(队列)生产者和消费者之间存在一个队列(作用在于解耦:解除程序间的耦合)
是否有队列存在的不同工作方式
相当于火车票的两种购买方式
第一种没有队列方式:
类比火车站售票口买票,同一时间的最大能处理任务的能力就是站在售票口的人,其他人需要排队。
缺点:占用资源、浪费时间、效率低下。
第二种有队列方式:
类比在12306上进行买票时,队列可以将更多的任务提前接收起来,然后独立的给后端窗口提供任务,那么这个队列的最大容量就是处理任务的最大负载。从经济学角度,12306其实卖的是期货,先把预授权卖给你,后台继续按照原有速度处理,不用大量排队,提交任务之后,就可以去干别的事了。
在此引入一个概念:队列,以规定好的读取顺序进行消息收集的一个集合
队列类型:
先进先出后进先出
优先级队列(设有权重)
双向队列
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 import queue ''' 队列:先进先出,后进先出,权重队列,双向队列 先进先出队列: 对象queue,可以设置队列最大容纳元素数q = queue.Queue(2) 放数据:put(self,item,block=False,timeout=None),默认阻塞,默认block=False 可设置block参数为True即为不阻塞,直接报错 取数据:get(self,item,block=False,timeout=None),默认阻塞,默认block=True 可设置block参数为True即为不阻塞,直接报错 qsize()队列真实长度 maxsize()最大支持个数 join,task_done,阻塞进程,当队列中任务执行完毕之后,不在阻塞 ''' #先进先出 q = queue.Queue(2) print(q.empty(),q.qsize()) q.put(11) q.put(231) print(q.qsize()) print(q.empty()) q.put(2) q.put(22,block=False) q.put(321,block=False,timeout=2) print(q.get()) print(q.get(timeout=2)) print(q.qsize()) #后进先出队列 q = queue.LifoQueue() q.put(123) q.put(345) print(q.get()) #优先级队列:第一个参数为权重值,值越小优先级越大,同权重时,先进先出 w = queue.PriorityQueue() w.put((1,'alex1')) w.put((2,'alex2')) w.put((1,'alex3')) w.put((3,'alex4')) print(w.get()) #双向队列:双向队列相当于两个连在一起的后进先出队列,因此从单边取数据时,是遵循后进先出原则 e = queue.deque() e.append(123) e.append(321) e.appendleft(43242) e.appendleft(564) print(e.pop()) print(e.pop()) print(e.popleft())
线程锁:防止产生脏数据,数据保护
行级锁:
LockRLock
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 import threading import time num = 10 def func(l): global num #上锁 l.acquire() num -= 1 time.sleep(1) print(num) #开锁 l.release() #acquire release 上锁 开锁成对出现 #Rlock既支持多层锁,也支持单层锁 lock = threading.RLock() #Lock只支持单层锁 #lock = threading.Lock() #BoundedSemaphore 信号量,参数表示每次放行几个线程操作, lock = threading.BoundedSemaphore(5) for i in range(10): t = threading.Thread(target=func,args=(lock,)) t.start()
块级锁:event
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 import threading def func(i,e): print(i) e.wait()#检侧是什么灯,如果是红灯,停;绿灯,行; print(i+100) event = threading.Event() for i in range(10): t = threading.Thread(target=func,args=(i,event,)) t.start() event.clear() #设置红灯 inp = input('>>>') if inp == '1': event.set()
条件判断锁:Condition
#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 import threading #使得线程等待,只有满足某条件时,才释放n个线程 # def condition(): # ret = False # r = input('>>>') # if r == True: # ret = True # else: # ret = False # return ret # # def func(i,con): # print(i) # con.acquire() # con.wait_for(condition) # print(i+100) # con.release() # # c = threading.Condition() # for i in range(10): # t = threading.Thread(target=func,args=(i,c,)) # t.start() def func(i,con): print(i) con.acquire() con.wait() print(i+100) con.release() c = threading.Condition() for i in range(10): t = threading.Thread(target=func,args=(1,c,)) t.start() while True: inp = input('>>>: ') if inp == 'q': break c.acquire() c.notify(int(inp)) c.release()
事务级锁:Samephare,执行不成功,则回退
补充:Timer#!/usr/bin/env python # -- coding = 'utf-8' -- # Author Allen Lee # Python Version 3.5.1 # OS Windows 7 from threading import Timer def hello(): print('hello,world') t = Timer(1,hello) #一秒后执行hello函数 t.start()
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- mongo实现消息队列
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例