PyQt6的QMutex与threading.Lock是否等效?多线程操作列表互斥失败问题
问题原因
你当前的互斥控制逻辑不生效,核心问题是每个线程实例持有独立的QMutex对象,没有共用同一个锁实例。
互斥锁实现多线程资源互斥访问的前提是所有操作共享资源的线程,都对同一个锁实例执行加锁/解锁操作。你目前在__init__方法中给每个Thread对象都初始化了新的QMutex,各个线程加锁时互不干扰,相当于没有加锁,自然会出现同时操作列表的问题。
你用Python原生threading.Lock时逻辑正常,大概率是你当时把Lock定义为了全局变量/类属性,所有线程共用同一个锁实例,符合互斥控制的要求。
修复方案
有两种常用的修改方式,保证所有线程共用同一个QMutex:
方案1:将QMutex定义为全局变量
import time from PyQt5.QtCore import QRunnable, QMutex, QThreadPool lst = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 全局锁,所有线程共用 global_mutex = QMutex() class Thread(QRunnable): def __init__(self): super().__init__() def run(self): global_mutex.lock() lst.pop(0) print(str(lst)) time.sleep(5) global_mutex.unlock()
方案2:将QMutex定义为类属性
类属性会被所有类实例共享,不需要额外定义全局变量:
class Thread(QRunnable): # 类属性锁,所有Thread实例共用 mutex = QMutex() def __init__(self): super().__init__() def run(self): self.mutex.lock() lst.pop(0) print(str(lst)) time.sleep(5) self.mutex.unlock()
优化建议
推荐使用QMutexLocker自动管理锁的释放,避免代码抛出异常时漏调用unlock导致死锁:
def run(self): # 加锁,出当前作用域时自动解锁 locker = QMutexLocker(global_mutex) lst.pop(0) print(str(lst)) time.sleep(5)
内容的提问来源于stack exchange,提问作者Larry
相关产品推荐
相关产品推荐

