📜  python中的信号量(1)

📅  最后修改于: 2023-12-03 15:34:25.987000             🧑  作者: Mango

Python中的信号量

在多线程和多进程的开发中,所涉及的共享资源可能会被多个线程或进程同时访问,如果这些线程或进程同时修改共享资源,就会引发一些问题,如数据竞争、死锁等。此时,就需要使用同步机制来对共享资源进行管理,以保证线程或进程之间资源的安全访问。Python提供了信号量Semaphore来实现同步机制。

信号量Semaphore是什么?

Semaphore(信号量)是一种同步原语,用来控制对共享资源的访问。Semaphore维护了一个计数器,该计数器表示当前可以访问共享资源的线程或进程的数量。当一个线程或进程需要使用共享资源时,它首先要获取一个信号量,如果信号量计数器为0,则线程或进程暂时不能访问共享资源,需要等待其他线程或进程释放信号量。当某个线程或进程完成对共享资源的访问后,它会释放它持有的信号量,此时信号量计数器加1,等待访问共享资源的线程或进程就可以继续获得信号量并进行访问。

在Python中,Semaphore是由threading模块提供的一个类,其构造函数如下:

Semaphore(value=1)

其中,value表示信号量计数器的初始值,默认为1。如果value大于1,则允许同时有多个线程或进程访问共享资源。

如何使用Semaphore?

Semaphore已经封装在Python的标准库中,因此使用时只需导入threading模块即可,如下所示:

import threading

Semaphore对象的使用有两个方法:

  • acquire([blocking]):获取一个信号量。如果Semaphore计数器的值大于0,则将计数器减1并返回True;否则如果blocking为True,则当前线程会阻塞直到有其他线程或进程释放了一个信号量;如果blocking为False,则该方法会立即返回False,表示未获取到信号量。
  • release():释放一个信号量。将Semaphore的计数器加1。

下面是一个简单的例子,使用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的使用可以保证线程或进程之间对共享资源的安全访问,避免出现数据竞争等问题。