1 基本介绍
semaphore信号量锁也是根据条件锁来做的,他与条件锁、事件锁的区别如下:
条件锁:一次可以放行任意个处于“等待”状态的线程
事件锁:一次可以放行全部的处于“等待”状态的线程
信号量锁:通过规定,成批的放行特定个处于“上锁”状态的线程
2 相关方法
| 方法 | 描述 |
|---|---|
| threading.Semaphore() | 返回一个信号量锁对象 |
| lockObject.acquire(blocking=True, timeout=1) | 上锁,当一个线程在执行被上锁代码块时,将不允许切换到其他线程运行,默认锁失效时间为1秒 |
| lockObject.release() | 解锁,当一个线程在执行未被上锁代码块时,将允许系统根据策略自行切换到其他线程中运行 |
3 使用示例
这里有2个示例
example01:
import threading
import time
def run(n, semaphore):
semaphore.acquire()
time.sleep(3)
print('run the thread:%s\n' % n)
semaphore.release()
def main():
# 最多允许两个线程同时运行
semaphore = threading.BoundedSemaphore(2)
for num in range(4):
t = threading.Thread(target=run, args=(f't-{num}', semaphore))
t.start()
if __name__ == '__main__':
main()
result:
run the thread:t-1
run the thread:t-0
run the thread:t-3
run the thread:t-2
example 02:
import threading
import time
sema = threading.BoundedSemaphore(2)
t_total = 0
def A(num):
sema.acquire()
print('Thread: %s' % num)
time.sleep(1)
sema.release()
return
def run_cmp_single():
for i in range(5):
t_a = threading.Thread(target=A, args=(i + 1,))
t_a.start()
if __name__ == '__main__':
run_cmp_single()
result;
Thread: 1
Thread: 2
Thread: 3
Thread: 4
Thread: 5
4 with语句
与同步锁一样,threading.Semaphore()对象中也实现了 enter() 与exit()方法,因此我们也可以像同步锁一样,使用with语句进行上下文管理形式来进行信号量锁的加锁解锁操作。
示例代码如下:
import threading
import time
def run(n, semaphore):
with semaphore:
time.sleep(3)
print('run the thread:%s\n' % n)
def main():
# 最多允许两个线程同时运行
semaphore = threading.BoundedSemaphore(2)
for num in range(4):
t = threading.Thread(target=run, args=(f't-{num}', semaphore))
t.start()
if __name__ == '__main__':
main()
result:
run the thread:t-1
run the thread:t-0
run the thread:t-3
run the thread:t-2
\