线程中的信号量和事件
Posted whylinux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程中的信号量和事件相关的知识,希望对你有一定的参考价值。
# 线程中的信号量 # 和进程中的信号量概念一样,创建好信号量的深度后,同一时间只有n个线程可以访问被信号量保护的代码 # 同一时间只有4个线程可以访问被信号量保护的代码 # import time # from threading import Semaphore, Thread # # def func(sem, a, b): # sem.acquire() # time.sleep(1) # print(a + b) # sem.release() # # if __name__ == ‘__main__‘: # # sem = Semaphore(4) # 创建信号量,4个深度 # for i in range(10): # t = Thread(target=func, args=(sem, i, i + 5)) # t.start() # 线程中的事件 # 和进程中的事件概念一样 # 事件的状态 # False状态 # wait()阻塞 # True状态 # wait()非阻塞 # 改变事件的状态 # clear()设置事件状态为Flase,即使wait()阻塞 # set()设置事件状态为True,即使wait()非阻塞 # 线程中的事件例子 # 模拟 # 连接数据库 # 检测数据库的可连接情况 # 起两个线程 # 第一个线程:连接数据库 # 第一个线程会阻塞等待这个事件,等待一个信号,这个信号来告诉自己和数据库之间的网络是通的 # 第二个线程:检测与数据库之间的网络是否是通的 # 模拟延时一会后,将事件的状态设置为True,使这个事件变为非阻塞,此时第一个线程就会检测到该事件为非阻塞,则会知道与数据库之间的网络是通的 import time import random from threading import Event, Thread def connect_db(e): ‘‘‘ 模拟检测数据库可以连接后,则连接数据库 :param e: :return: ‘‘‘ count = 3 while count > 0: #e.wait() # 如果事件e为False,则会阻塞在这里 e.wait(1) # wait可以带参数,表示如果事件是阻塞的话,这里最长会阻塞1S中 if e.is_set() == True: # 检测下事件是否为非阻塞,因为到这里可能是wait阻塞超时导致(这种事件状态还是为False阻塞),也可能确实是检测网络的线程发的解除阻塞信号 print(‘连接数据库‘) break else: print(‘连接数据库超时‘) count -= 1 else: print(‘连接数据库到了上限次还没有连接数据库成功‘) raise TimeoutError # 主动抛出一个超时异常 def check_web(e): ‘‘‘ 检测数据库可连接情况,模拟延时一会后,将事件设置为True,变为非阻塞,表示网络是通的 :param e: 事件 :return: ‘‘‘ time.sleep(random.randint(0, 5)) e.set() if __name__ == ‘__main__‘: e = Event() # 事件创建好后,默认是False阻塞的 t = Thread(target=connect_db, args=(e, )) t2 = Thread(target=check_web, args=(e, )) t.start() t2.start() t.join() t2.join()
以上是关于线程中的信号量和事件的主要内容,如果未能解决你的问题,请参考以下文章
网络编程基础--多线程---concurrent.futures 模块---事件Event---信号量Semaphore---定时器Timer---死锁现象 递归锁----线程队列queue(示例代码