2019独角兽企业重金招聘Python工程师标准>>>
threading
threading模块方法
方法 | 释义 |
---|---|
threading.Lock() | 互斥锁/同步锁 |
threading.RLock() | 递归锁 |
threading.Event() | 同步对象 |
threading.currentThread() | 返回当前的线程变量 |
threading.enumerate() | 返回一个包含正在运行的list。正在运行指线程启动后、结束前,不包含启动前和终止后的线程 |
threading.activeCount() | 返回正在运行的线程数量,与len(threading.enumerate())有相同结果 |
threading.Lock()
多线程示例 - 线程不安全
==错误示例【因所有线程多任务处理争夺处理器资源取初始化测试值造成结果错误!】==
# -*- coding:utf-8 -*--
import threading,time
num = 100 #初始化测试值
def sub(): #定义测试函数
global num #引入测试值
temp = num #测试值赋予新值
time.sleep(0.001) #增加运行时间便于查看测试结果
num = temp - 1 #测试运算方式
l = [] #建立空列表便于添加线程对象
for i in range(100): #启用线程
t = threading.Thread(target=sub)
t.start()
l.append(t)
for i in l: #遍历所有线程
t.join() #守护主进程
print(num) #输出结果
95
错误示例解决方案 - 使用互斥锁-threading.Lock 相当于并行变串行
# -*- coding:utf-8 -*--
import threading,time
num = 100 #初始化测试值
def sub(): #定义测试函数
global num #引入测试值
lock.acquire() #获得同步锁,只允许一个线程使用处理器资源
temp = num #测试值赋予新值
time.sleep(0.001) #增加运行时间便于查看测试结果
num = temp - 1 #测试运算方式
lock.release() #释放同步锁
l = [] #建立空列表便于添加线程对象
lock = threading.Lock() #建立同步锁
for i in range(100): #启用线程
t = threading.Thread(target=sub)
t.start()
l.append(t)
for i in l: #遍历所有线程
t.join() #守护主进程
print(num) #输出结果
0
threading.RLock()
死锁模拟,进程一直处于等待
# -*- coding:utf-8 -*-
import threading,time
class MyThread(threading.Thread):
def actionA(self):
A.acquire() #锁定 A 锁 第一个线程获得其它线程等待
print("当前锁名称:",self.name,"当前时间:",time.ctime())
time.sleep(2)
B.acquire() #锁定 B 锁 第二个线程对B锁有需求,但B锁在第一个线程未释放,要等待第一个线程释放 【造成死锁】
print("当前锁名称:", self.name, "当前时间:", time.ctime())
time.sleep(1)
B.release() #释放 B 锁
A.release() #释放 A 锁 第一个线程释放,其他线程执行
def actionB(self):
B.acquire() #锁定 B 锁 第一个线程获得B锁,同一时刻下个进程获得A锁
print("当前锁名称:",self.name,"当前时间:",time.ctime())
time.sleep(2)
A.acquire() #锁定 A 锁 第一个线程对A锁有需求,但A锁第二个线程未释放,要等待第二个线程释放 【造成死锁】
print("当前锁名称:", self.name, "当前时间:", time.ctime())
time.sleep(1)
A.release() #释放 A 锁
B.release() #释放 B 锁
def run(self): #所有线程同时执行此方法
self.actionA()
self.actionB()
if __name__ == '__main__':
A = threading.Lock() #创建 A 锁
B = threading.Lock() #创建 B 锁
L = []
for i in range(5): #模拟创建5个线程
t = MyThread()
t.start()
L.append(t)
for i in L:
i.join()
print("程序结束!")
###### 注意:程序并未完成,处于一直等待释放阶段~ #########
当前锁名称: Thread-1 当前时间: Mon Jun 4 19:49:49 2018
当前锁名称: Thread-1 当前时间: Mon Jun 4 19:49:51 2018
当前锁名称: Thread-2 当前时间: Mon Jun 4 19:49:52 2018
当前锁名称: Thread-1 当前时间: Mon Jun 4 19:49:52 2018
用递归锁-threading.RLock() 避免死锁情况发生,线程未释放同名称锁别的线程无法获取锁处于等待中
# -*- coding:utf-8 -*-
import threading,time
class MyThread(threading.Thread):
def actionA(self):
R_Lock.acquire() #锁定 rlock 锁
print("当前锁名称:",self.name,"当前时间:",time.ctime())
time.sleep(2)
R_Lock.acquire() #锁定 rlock 子锁
print("当前锁名称:", self.name, "当前时间:", time.ctime())
time.sleep(1)
R_Lock.release() #释放 rlock 子锁
R_Lock.release() #释放 rlock 锁
def actionB(self):
R_Lock.acquire() #锁定 rlock 锁
print("当前锁名称:",self.name,"当前时间:",time.ctime())
time.sleep(2)
R_Lock.acquire() #锁定 rlock 子锁
print("当前锁名称:", self.name, "当前时间:", time.ctime())
time.sleep(1)
R_Lock.release() #释放 rlock 子锁
R_Lock.release() #释放 rlock 锁
def run(self): #所有线程同时执行此方法
self.actionA()
self.actionB()
if __name__ == '__main__':
# A = threading.Lock()
# B = threading.Lock()
R_Lock = threading.RLock() #创建 rlock 递归锁
L = []
for i in range(5): #模拟创建5个线程
t = MyThread()
t.start()
L.append(t)
for i in L:
i.join()
print("程序结束!")
当前锁名称: Thread-1 当前时间: Mon Jun 4 20:05:33 2018
当前锁名称: Thread-1 当前时间: Mon Jun 4 20:05:35 2018
当前锁名称: Thread-2 当前时间: Mon Jun 4 20:05:36 2018
当前锁名称: Thread-2 当前时间: Mon Jun 4 20:05:38 2018
当前锁名称: Thread-3 当前时间: Mon Jun 4 20:05:39 2018
当前锁名称: Thread-3 当前时间: Mon Jun 4 20:05:41 2018
当前锁名称: Thread-4 当前时间: Mon Jun 4 20:05:42 2018
当前锁名称: Thread-4 当前时间: Mon Jun 4 20:05:44 2018
当前锁名称: Thread-4 当前时间: Mon Jun 4 20:05:45 2018
当前锁名称: Thread-4 当前时间: Mon Jun 4 20:05:47 2018
当前锁名称: Thread-1 当前时间: Mon Jun 4 20:05:48 2018
当前锁名称: Thread-1 当前时间: Mon Jun 4 20:05:50 2018
当前锁名称: Thread-2 当前时间: Mon Jun 4 20:05:51 2018
当前锁名称: Thread-2 当前时间: Mon Jun 4 20:05:53 2018
当前锁名称: Thread-3 当前时间: Mon Jun 4 20:05:54 2018
当前锁名称: Thread-3 当前时间: Mon Jun 4 20:05:56 2018
当前锁名称: Thread-5 当前时间: Mon Jun 4 20:05:57 2018
当前锁名称: Thread-5 当前时间: Mon Jun 4 20:05:59 2018
当前锁名称: Thread-5 当前时间: Mon Jun 4 20:06:00 2018
当前锁名称: Thread-5 当前时间: Mon Jun 4 20:06:02 2018
程序结束!
threading.Event()
事件Event同步线程
名称 | 释义 |
---|---|
event.isSet() | 返回event状态值False或True |
event.wait() | 如果event状态为False,将阻塞线程 |
event.set() | 默认设定event为True |
event.clear() | 恢复event的状态为False |
示例:
# -*- coding:utf-8 -*-
import threading,time
class Boss(threading.Thread):
def run(self):
print("BOSS:今天晚上加班到22:00")
print("event.set【设定前】event状态:",event.isSet())
event.set() #【阻塞】 - 设定event.set标志位
print("event.set【设定后】event状态:", event.isSet())
#等待阻塞状态清空后才可以执行以下代码
time.sleep(5)
print("BOSS:现在可以下班了!!!")
event.set()
class Worker(threading.Thread):
def run(self):
event.wait() #【阻塞】 - 标志位被设定
print("员工:命真苦~")
event.clear() #【清空状态】 - 阻塞状态清空
event.wait() #【阻塞】 - 标志位被设定
print("员工:解放了!")
if __name__ == '__main__':
event = threading.Event() #创建Event对象
L = []
for i in range(3): #建立多线程
L.append(Worker())
L.append(Boss())
for t in L: #启用多线程
t.start()
for t in L: #等待线程
t.join()
print("end")
BOSS:今天晚上加班到22:00
event.set【设定前】event状态: False
event.set【设定后】event状态: True
员工:命真苦~
员工:命真苦~
员工:命真苦~
BOSS:现在可以下班了!!!
员工:解放了!
员工:解放了!
员工:解放了!
end