Python多线程同步是指保证多个线程之间的数据安全和执行顺序正确。为了实现这个目标,Python提供了多种同步机制,其中包括Lock、RLock、Semaphore、Event等实例。
Lock
Lock是最基础的线程同步实例,它使用二元信号量算法来保持同步。当一个线程获得了Lock的锁时,其他线程就不能再获取这个锁,直到该线程释放这个锁为止。
下面是一个Lock实例的示例代码:
import threading
class Counter():
def __init__(self):
self.count = 0
self.lock = threading.Lock()
def increment(self):
self.lock.acquire()
self.count += 1
self.lock.release()
def worker(counter):
for i in range(1000):
counter.increment()
counter = Counter()
threads = []
for i in range(10):
t = threading.Thread(target=worker, args=(counter,))
threads.append(t)
t.start()
for t in threads:
t.join()
print(counter.count)
在这个示例中,定义了一个Counter类,其中increment方法用来实现count的自增。使用Lock实例来保证在同时进行自增时不会产生数据竞争的问题。具体来说,每个线程在执行increment方法前,需要先调用lock.acquire()方法获取锁,执行完后再调用lock.release()方法释放锁。
RLock
RLock是可重入锁,它可以被同一个线程多次获取,但是要保证同样数量的释放操作才能释放该锁。
下面是一个RLock实例的示例代码:
import threading
class MyThread(threading.Thread):
def __init__(self, lock):
threading.Thread.__init__(self)
self.lock = lock
def run(self):
self.lock.acquire()
print('Thread {} acquired the lock.'.format(self.name))
self.lock.acquire()
print('Thread {} re-acquired the lock.'.format(self.name))
self.lock.release()
print('Thread {} released the lock.'.format(self.name))
self.lock.release()
print('Thread {} released the lock again.'.format(self.name))
lock = threading.RLock()
t1 = MyThread(lock)
t2 = MyThread(lock)
t1.start()
t2.start()
t1.join()
t2.join()
在这个示例中,使用RLock保护了两个线程中的临界区。首先线程1获取了锁,在后面又获取了一次锁,这是RLock可以允许的。之后释放了锁,另一个线程才有机会执行,最后线程1再次释放锁。注意必须保证释放锁的操作数量和获取锁的操作数量相同。
Semaphore
Semaphore是一种可用于控制并发线程数量的同步实例,其具有一个计数器,初始化时设置计数器的值,每当一个线程调用semaphore.acquire()时,计数器的值减一,当计数器为零时,再有线程调用semaphore.acquire()时就会被阻塞,直到计数器大于零。
下面是一个Semaphore实例的示例代码:
import threading
sem = threading.Semaphore(2)
def worker():
sem.acquire()
print('Thread {} acquired the semaphore.'.format(threading.current_thread().name))
sem.acquire()
print('Thread {} re-acquired the semaphore.'.format(threading.current_thread().name))
sem.release()
print('Thread {} released the semaphore.'.format(threading.current_thread().name))
sem.release()
print('Thread {} released the semaphore again.'.format(threading.current_thread().name))
threads = []
for i in range(4):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
for t in threads:
t.join()
在这个示例中,使用Semaphore来控制并发线程的数量。每次只有两个线程可以获取信号量,所以每次运行时只有两个线程可以运行,其余的线程都被阻塞等待。
Event
Event是一种可以用来通知线程之间的状态变化的同步实例。Event由一个内部的标志属性表示状态,该标志初始为False,当该标志变为True时,等待该Event的线程就会被唤醒。
下面是一个Event实例的示例代码:
import threading
event = threading.Event()
def wait_for_event():
print('Thread {} is waiting for event.'.format(threading.current_thread().name))
event.wait()
print('Thread {} is now executing its thread code.'.format(threading.current_thread().name))
threads = []
for i in range(3):
t = threading.Thread(target=wait_for_event)
threads.append(t)
t.start()
event.set()
print('Event has been set')
for t in threads:
t.join()
在这个示例中,三个线程等待着event的发生,当event被set时,就会唤醒所有等待它的线程,使它们继续执行自己的任务,最后三个线程都执行完了自己的任务。
总之,Lock、RLock、Semaphore、Event都是Python多线程同步不可或缺的机制。在实际应用中,需要根据具体情况来选择合适的同步机制,以保证多线程执行的正确性和效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多线程同步Lock、RLock、Semaphore、Event实例 - Python技术站