📅  最后修改于: 2023-12-03 15:34:25.987000             🧑  作者: Mango
在多线程和多进程的开发中,所涉及的共享资源可能会被多个线程或进程同时访问,如果这些线程或进程同时修改共享资源,就会引发一些问题,如数据竞争、死锁等。此时,就需要使用同步机制来对共享资源进行管理,以保证线程或进程之间资源的安全访问。Python提供了信号量Semaphore来实现同步机制。
Semaphore(信号量)是一种同步原语,用来控制对共享资源的访问。Semaphore维护了一个计数器,该计数器表示当前可以访问共享资源的线程或进程的数量。当一个线程或进程需要使用共享资源时,它首先要获取一个信号量,如果信号量计数器为0,则线程或进程暂时不能访问共享资源,需要等待其他线程或进程释放信号量。当某个线程或进程完成对共享资源的访问后,它会释放它持有的信号量,此时信号量计数器加1,等待访问共享资源的线程或进程就可以继续获得信号量并进行访问。
在Python中,Semaphore是由threading模块提供的一个类,其构造函数如下:
Semaphore(value=1)
其中,value表示信号量计数器的初始值,默认为1。如果value大于1,则允许同时有多个线程或进程访问共享资源。
Semaphore已经封装在Python的标准库中,因此使用时只需导入threading模块即可,如下所示:
import threading
Semaphore对象的使用有两个方法:
下面是一个简单的例子,使用Semaphore实现线程的同步:
import threading
# 定义一个Semaphore对象,初始值为1
semaphore = threading.Semaphore(1)
def worker():
# 获取Semaphore
semaphore.acquire()
print('Worker {} starts to work'.format(threading.current_thread().name))
# 模拟耗时操作
for i in range(5):
print('Worker {} is working ({}/{})'.format(threading.current_thread().name, i+1, 5))
# 释放Semaphore
semaphore.release()
print('Worker {} finishes work'.format(threading.current_thread().name))
# 创建两个线程
t1 = threading.Thread(target=worker, name='Thread-1')
t2 = threading.Thread(target=worker, name='Thread-2')
# 启动线程
t1.start()
t2.start()
# 等待线程执行完毕
t1.join()
t2.join()
输出结果如下:
Worker Thread-1 starts to work
Worker Thread-1 is working (1/5)
Worker Thread-1 is working (2/5)
Worker Thread-1 is working (3/5)
Worker Thread-1 is working (4/5)
Worker Thread-1 is working (5/5)
Worker Thread-1 finishes work
Worker Thread-2 starts to work
Worker Thread-2 is working (1/5)
Worker Thread-2 is working (2/5)
Worker Thread-2 is working (3/5)
Worker Thread-2 is working (4/5)
Worker Thread-2 is working (5/5)
Worker Thread-2 finishes work
可以看到,两个线程交替执行了5次,Semaphore保证了每个时刻只有一个线程在执行工作。如果没有Semaphore的保护,两个线程会同时访问共享资源,可能会发生数据竞争等问题。
Semaphore是一种同步原语,用来控制对共享资源的访问。Python提供了Semaphore类来实现同步机制,其主要方法是acquire和release。Semaphore的使用可以保证线程或进程之间对共享资源的安全访问,避免出现数据竞争等问题。