Semaphore(信号量)
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。
import threading,time
def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" %n)
semaphore.release()
if __name__ == '__main__':
num= 0
semaphore = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
for i in range(20):
t = threading.Thread(target=run,args=(i,))
t.start()
while threading.active_count() != 1:
pass #print threading.active_count()
else:
print('----all threads done---')
print(num)
Events的使用
event = threading.Event()
event.wait()
Event对象wait的方法只有在内部信号为真的时候才会很快的执行并完成返回。当Event对象的内部信号标志位假时,则wait方法一直等待到其为真时才返回。
event.set()
使用Event的set()方法可以设置Event对象内部的信号标志为真。Event对象提供了isSet()方法来判断其内部信号标志的状态。当使用event对象的set()方法后,isSet()方法返回真
event.clear()
使用Event对象的clear()方法可以清除Event对象内部的信号标志,即将其设为假,当使用Event的clear方法后,isSet()方法返回假。
线程同步之条件变量
互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持。
Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。
线程首先acquire一个条件变量,然后判断一些条件。
- 如果条件不满足则wait;
- 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
示例如下:
#coding=utf-8
import threading
import time
class A(threading.Thread):
def run(self):
while True:
if con.acquire():
print('---A---1---')
con.wait()
print('---A---2---')
con.release()
time.sleep(1)
class B(threading.Thread):
def run(self):
while True:
if con.acquire():
raw_input('输入任意字符:')
con.notify()
con.release()
time.sleep(1)
con = threading.Condition()
if __name__ == '__main__':
a = A()
a.start()
b = B()
b.start()
python事件Event相关函数介绍
set() — 全局内置标志Flag,将标志Flag 设置为 True,通知在等待状态(wait)的线程恢复运行;
isSet() — 获取标志Flag当前状态,返回True 或者 False;
wait() — 一旦调用,线程将会处于阻塞状态,直到等待其他线程调用set()函数恢复运行;
clear() — 将标志设置为False;
python事件Event原理
事件event中有一个全局内置标志Flag,值为 True 或者False。使用wait()函数的线程会处于阻塞状态,此时Flag指为False,直到有其他线程调用set()函数让全局标志Flag置为True,其阻塞的线程立刻恢复运行,还可以用isSet()函数检查当前的Flag状态.
案例:
第一个线程中获取当前时间,判断当前时间3秒之后,触发“事件” 对象。在另
一个线程中,作为数学考试结束的判断变量,否则一直处于考试中,并打印。
import threading # 导入线程类
import time # 导入python中的time类
class OneThread(threading.Thread): # 自定义线程类继承于Thread类
def __init__(self): # 定义构造方法
super(OneThread, self).__init__() # 重写Thread类的构造方法初始化self属性
def run(self): # 重写Thread类的run方法,执行实际逻辑结构
while True: # while循环判断事件是否响应
print("考试中") # 若事件未响应则输出“考试中”的信息
time.sleep(1) # 使线程挂起1秒,减少输出次数
if event.is_set(): # 若事件响应
print("考试结束!") # 则输出“考试结束”的信息
break # 停止并跳出循环
class InheritThread(threading.Thread): # 定义事件监听类继承于Thread类
def __init__(self): # 构造方法
super(InheritThread, self).__init__() # 重写Thread类的构造方法并初始化self属性
def run(self): # 重写Thread类的run方法
for i in range(3): # 循环3秒
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) # 输出显示当前的时间
time.sleep(1) # 使线程挂起1秒,减少输出次数
event.set() # 设置事件响应
if __name__ == '__main__': # 创建主线程
event = threading.Event() # 初始化event对象
First = OneThread() # 初始化一个线程对象
Second = InheritThread() # 初始化一个线程对象
First.start() # 启动线程
Second.start() # 启动线程