Semaphore工作原理:
Semaphore
对象支持上下文管理协议。1.acquire(blocking=True, timeout=None)
2.release()
该计数器由每个acquire()
调用递减,并由每个release()
调用递增。计数器永远不会低于零,当acquire()
发现计数器为零时,线程阻塞,等待其他线程调用release()
。
当
blocking=True
时:如果调用时计数器大于零,则将其减1并立即返回。如果在调用时计数器为零,则阻塞并等待,直到其他线程调用release()
使其大于零。因此如果多个acquire()
被阻塞,release()
将只唤醒其中一个,这个过程会随机选择一个,因此不应该依赖阻塞线程的被唤醒顺序。
计算方式:release()调用数减去acquire()调用数加一个初始值的计数器
FooBar
实例。其中一个线程将会调用 foo()
方法,另一个线程将会调用 bar()
方法。输入: n = 1
输出: "foobar"
解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。
思路:信号交替,调用acquire()则+1 ,调用release()则 -1
1 import threading 2 3 4 class FooBar: 5 def __init__(self, n): 6 self.n = n 7 self.demotex1 = threading.Semaphore(1) 8 self.demotex2 = threading.Semaphore(0) 9 10 11 def foo(self, printFoo: 'Callable[[], None]') -> None: 12 13 for i in range(self.n): 14 self.demotex1.acquire() # -1 15 # printFoo() outputs "foo". Do not change or remove this line. 16 printFoo() 17 self.demotex2.release() # +1 释放信号,使计数器递增1。当计数器为零并有另一个线程等待计数器大于零时,唤醒该线程。 18 19 20 21 def bar(self, printBar: 'Callable[[], None]') -> None: 22 23 for i in range(self.n): 24 self.demotex2.acquire() 25 # printBar() outputs "bar". Do not change or remove this line. 26 printBar() 27 self.demotex1.release()
该题来自力扣