📅  最后修改于: 2023-12-03 14:44:58.225000             🧑  作者: Mango
在操作系统中,二元信号量(也称为互斥量)和互斥锁是用于协调并发访问共享资源的基本工具。它们允许线程或进程在访问共享资源时相互排斥,以避免竞争条件和死锁等问题。
二元信号量是一个计数器,只有两种值:0和1。当它的值为1时,表示资源可用,线程可以访问它。当它的值为0时,表示资源不可用,线程必须等待其他线程释放该资源。因为它只有两个值,所以又称为二元信号量或二元信号灯。
二元信号量通过两个操作来实现:
例如,下面是一个使用二元信号量实现的简单生产者-消费者模型:
from threading import Semaphore, Thread
semaphore = Semaphore(0)
buffer = None
def producer():
global buffer
# Produce item
buffer = "Hello"
# Signal consumer
semaphore.release()
def consumer():
global buffer
# Wait for item
semaphore.acquire()
# Consume item
print(buffer)
t1 = Thread(target=producer)
t2 = Thread(target=consumer)
t1.start()
t2.start()
在这个例子中,生产者线程通过设置buffer变量来生产一个项目,并使用semaphore.release()向消费者线程发出信号。消费者线程通过semaphore.acquire()等待信号,并在接收到信号后消费buffer中的项目。
互斥锁是另一种协调并发访问共享资源的工具。与二元信号量不同,互斥锁可以跟踪哪个线程目前持有锁,并保证只有一个线程可以持有锁。
互斥锁通过两个操作来实现:
例如,下面是一个使用互斥锁实现的简单计数器:
from threading import Lock, Thread
counter = 0
lock = Lock()
def increment():
global counter
with lock:
counter += 1
threads = []
for i in range(10):
t = Thread(target=increment)
threads.append(t)
t.start()
for t in threads:
t.join()
print(counter)
在这个例子中,多个线程并发访问计数器变量counter,但是由于使用了互斥锁lock,每次只有一个线程能够获得锁并增加计数器变量的值。最终输出的counter变量值应该是10。
总结一下,二元信号量和互斥锁都是操作系统中用于协调并发访问共享资源的基本工具。二元信号量只有两个值(0或1),它用于线程之间的独占或相互排斥。互斥锁则是一个可拥有的标记,它用于控制多个线程对共享资源的访问。决定使用哪个工具取决于具体情况需求。