本文共 2052 字,大约阅读时间需要 6 分钟。
在多线程编程中,共享进程资源和地址空间可能导致公共资源出现异常结果。因此,线程同步与互斥机制至关重要。
考虑以下Python多线程示例:
import threadingcount = 0def print_time(threadName): global count c = 0 while(c < 100): c += 1 count += 1 print(f"{threadName}: set count to {count}") try: threading.Thread(target=print_time, args=("Thread-1",)).start() threading.Thread(target=print_time, args=("Thread-2",)).start() threading.Thread(target=print_time, args=("Thread-3",)).start()except Exception as e: print("Error: unable to start thread") 此代码启动三个线程,每个线程修改全局资源count,结果呈现交替执行的现象:
Thread-1: set count to 198Thread-2: set count to 199Thread-1: set count to 200Thread-2: set count to 201Thread-1: set count to 202Thread-2: set count to 203Thread-1: set count to 204
通过在print_time中加锁,可以确保函数的线程安全:
import threadingcount = 0lock = threading.Lock()def print_time(threadName): global count c = 0 with lock: while(c < 100): c += 1 count += 1 print(f"{threadName}: set count to {count}") try: threading.Thread(target=print_time, args=("Thread-1",)).start() threading.Thread(target=print_time, args=("Thread-2",)).start() threading.Thread(target=print_time, args=("Thread-3",)).start()except Exception as e: print("Error: unable to start thread") 加锁后输出如下:
Thread-2: set count to 199Thread-2: set count to 200Thread-3: set count to 201Thread-3: set count to 202Thread-3: set count to 203Thread-3: set count to 204
在threading模块中,定义两种锁类型:Lock和RLock。
Lock对象:
lock = threading.Lock()lock.acquire() # 产生一个死锁lock.acquire() # 阻塞当前线程lock.release() # 解锁lock.release() # 释放资源
RLock对象:
rLock = threading.RLock()rLock.acquire() # 非阻塞获取锁rLock.acquire() # 同一线程可重复获取rLock.release() # 成对释放锁rLock.release() # 解锁
RLock允许在同一线程中多次获取锁,而Lock不允许这种情况。使用RLock时,acquire和release必须成对调用。
通过上述示例可以看出,线程锁是实现多线程安全的关键机制。在Python中,threading.Lock和threading.RLock提供了灵活的锁管理方式,适用于不同的应用场景。理解这些机制有助于开发高效且线程安全的多线程应用程序。
转载地址:http://efofk.baihongyu.com/