您的位置:首页 > 编程语言 > Python开发

Python-开发之路-线程基础

2016-07-23 08:42 573 查看
引例:

#!/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())


线程锁:防止产生脏数据,数据保护

行级锁:

Lock

RLock

#!/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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息