2
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 线程库中重新创建它时,它按预期工作。我在这里做错了什么?

4

1 回答 1

1

问题是您为每个线程创建了一个互斥锁。互斥锁只保护使用相同互斥锁的线程。由于每个线程都使用自己的私有锁,因此它只能保护自己。扩展@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()
于 2021-09-12T17:39:22.670 回答