信号量(Semaphore)
threading模块里的Semaphore类实现了信号量对象,可用于控制获取资源的线程数量。所具有的acquire()和release()方法,可以用with语句的上下文管理器。当进入时,将调用acquire()方法,当退出时,将调用release()。
Semaphore跟Lock类似,但是Semaphore可以允许指定最多多少个进程访问资源。就像该资源有多个门,每个门一把锁。一个进程访问了资源,锁了门,还有其他门可以使用。但是如果所有门都被使用了,那么就得等待有进程出来释放锁才可以。
'''信号量'''
import threading
import time
def run(n):
semaphore.acquire()
print("线程:",n)
time.sleep(1)
semaphore.release()
if __name__ == '__main__':
#设置信号量
semaphore = threading.Semaphore(2)#每2个同时执行
for i in range(5):
t = threading.Thread(target=run,args=(i,))
t.start()
运行结果:
线程:0线程:1
线程:2线程:3
线程:4线程:5
线程:6线程:7
线程:8线程:9
条件变量(Conditional variable)
Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法唤醒其他线程,其他处于wait状态的线程接到唤醒后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
'''条件变量'''
import threading
import time
def run(n):
con.acquire()
print(f'线程:{n}')
con.notify()#启动该线程时唤醒其他线程启动
print(f'线程:{n}挂起')
con.wait()#令其等待
time.sleep(1)
print(f'线程:{n}再次启动')
con.notify()
con.release()
#同时运行
if __name__ == '__main__':
con = threading.Condition()#条件变量
for i in range(10):
t = threading.Thread(target=run,args=(i,))
t.start()
线程:0
线程:0挂起
线程:1
线程:1挂起
线程:0再次启动
线程:2
线程:2挂起
线程:3
线程:3挂起
线程:4
线程:4挂起
线程:5
线程:5挂起
线程:6
线程:6挂起
线程:5再次启动
线程:8
线程:8挂起
线程:9
线程:9挂起
线程:1再次启动
线程:2再次启动
线程:3再次启动
线程:4再次启动
线程:7
线程:7挂起
线程:6再次启动
线程:8再次启动
线程:9再次启动
事件(Event)
Python提供了Event对象用于线程间通信,它是由线程设置的信号标志,如果信号标志位真,则其他线程等待直到信号接触。事件对象可以通过通知操作的方式来保持线程的同步,并且可以实现不同进程中的线程同步操作。
Event对象实现了简单的线程通信机制,它提供了设置信号
set()
,清除信号clear()
,等待wait()
等用于实现线程间的通信。
'''事件'''
import threading
import time
def car():
#死循环,让其检测事件是否被设置
while True:
if event.is_set():#如果事件被设置
print('小车行驶')
else:
print('小车停止')
event.wait()#如果事件被清除则wait
def set_event():
#死循环,一直让其设置/取消事件
while True:
event.set()#设置事件
time.sleep(1) #在这1秒内会重复打印'小车行驶',因为线程car1一直在检测
event.clear() #清除事件
time.sleep(1) #在这1秒内不会重复打印,因为线程car1在wait
#随后循环到开头,事件继续被设置,继续打印‘小车行驶’
if __name__ == '__main__':
event = threading.Event()
#线程启动,两个线程同时进行
car1 = threading.Thread(target=car)
car1.start()
set1 = threading.Thread(target=set_event)
set1.start()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99498.html