pyqt6 QThread, threading.Lock() equivalent?


lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
class Thread(QRunnable):
def __init__(self):
super(Thread, self).__init__()
self.mutex = QMutex()
def run(self):
self.mutex.lock()
lst.pop(0)
print(str(lst))
time.sleep(5)
self.mutex.unlock()

上面的代码是我想要实现的一个例子,我有一个在类之外定义的列表。我想周期性地弹出列表的第一个元素。如果我正在运行5个线程,我只希望一个线程在一次改变列表。每次我尝试这5线程都试图弹出第一个元素,而不是等待我想要的。当我在本地python线程库中重新创建它时,它按预期工作。我哪里做错了?

问题是您为每个线程创建了一个互斥锁。互斥锁只保护使用相同互斥锁的线程。由于每个线程都使用自己的私有锁,所以它只对自己进行保护。扩展@eyllanesc答案,我创建了一个互斥锁供所有线程使用。互斥锁应该与它所保护的数据相关联。

import sys
import time
from PyQt6.QtCore import QCoreApplication, QMutex, QRunnable, QThreadPool, QTimer
# data with mutex access controls    
mutex = QMutex()
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]

class Thread(QRunnable):
def run(self):
#mutex = QMutex()    <-- don't create a private mutex
mutex.lock()
lst.pop(0)
print(lst, time.time()-start, flush=True)
time.sleep(5)
mutex.unlock()
start = time.time()
def main():
app = QCoreApplication(sys.argv)
QTimer.singleShot(8 * 1000, QCoreApplication.quit)
pool = QThreadPool()
for i in range(5):
runnable = Thread()
pool.start(runnable)
sys.exit(app.exec())

if __name__ == "__main__":
main()

最新更新