python线程信号量和事件

信号量Semaphore

同进程的一样

Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为5):

from threading import Thread,Semaphore
import threading
import time
# def func():
# if sm.acquire():
# print (threading.currentThread().getName() + ' get semaphore')
# time.sleep(2)
# sm.release()
def func():
 sm.acquire()
 print('%s get sm' %threading.current_thread().getName())
 time.sleep(3)
 sm.release()
if __name__ == '__main__':
 sm=Semaphore(5)
 for i in range(23):
 t=Thread(target=func)
 t.start()

Event

同进程的一样

线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行

event.isSet():返回event的状态值;

event.wait():如果 event.isSet()==False将阻塞线程;

event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;

event.clear():恢复event的状态值为False。

简单案例

from threading import Thread,Event
import threading
import time,random
def conn_mysql():
 count=1
 while not event.is_set():
 if count > 3:
 raise TimeoutError('链接超时')
 print('<%s>第%s次尝试链接' % (threading.current_thread().getName(), count))
 event.wait(0.5)
 count+=1
 print('<%s>链接成功' %threading.current_thread().getName())


def check_mysql():
 print('\033[45m[%s]正在检查mysql\033[0m' % threading.current_thread().getName())
 time.sleep(random.randint(2,4))
 event.set()
if __name__ == '__main__':
 event=Event()
 conn1=Thread(target=conn_mysql)
 conn2=Thread(target=conn_mysql)
 check=Thread(target=check_mysql)

conn1.start()
 conn2.start()
 check.start()

定时器

定时器,指定n秒后执行某操作

from threading import Timer
def hello():
 print("hello, world")

t = Timer(1, hello)
t.start() # after 1 seconds, "hello, world" will be printed

python线程信号量和事件
http://www.jcwit.com/article/109/
作者
Carlos
发布于
2018年6月18日
许可协议