python - pyqt6 QThread,threading.Lock() 等效?
问题描述
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()
推荐阅读
- javascript - 如何绑定 vue json schema 和 element-ui select?
- xamarin - Xamarin Forms:在焦点上添加 ItemSource
- css - 无法在 Reactjs、Webpack 中加载背景图片
- javascript - 如何使用 toggle() 在表单更改时更新 UI(例如单击复选框时)
- extjs - 分机在tabpanel中设置默认面板
- mongodb - MongoDB collection.aggregate 用于检索计数
- ubuntu - 以非根用户身份运行 Nginx Ubuntu 16.04
- c# - SQL 异常 - 网络相关或特定于实例。SQL Express“它适用于我的机器”问题
- neo4j - Neo4j 和 Java:什么是最好的?
- node.js - MongoDB 填充性能