You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:21:00