您的位置:首页 > 编程语言 > Qt开发

Qt多线程编程示例--代码基于python

2018-04-01 01:48 1126 查看
前言

本教程适合像我一样接触多线程不深的新手,也适合pyQt或qt新手,大神勿喷,主要用于自己学习总结。由于今天需要处理1000多个视频的相关工作,以往那种直接new很多个QThread的操作会直接卡死,所以模拟了一个线程池,同时只并行几个任务,余下的任务在队列等候,很像我们平时下载东西时那样子。下面这个示例是我编程的一个结构和思路,比较简单,大家不妨看看。当然,Qt也自带了线程池QThreadPool,配合QRunable对象,也能达到类似效果。但是我比较喜欢用QObject移动到线程这种方式,所以就自己写了点代码。以下就是整个步骤,其中线程管理类代码时完整的,其它2个类只给出了思路代码。写博客时,我代码还在跑,刚崩了一次,目测有BUG。现在换成DEBUG模式跑,明天起来看情况改代码,嘿嘿。

Qt多线程步骤

#-----------------步骤1,创建一个耗时操作类,专门执行耗时操作-----------#
class OP(qt.QObject):
#---定义结束信号,用来停止线程---#
finished = qt.pyqtSignal()
def __init__(self,arg):
super(OP,self).__init__()
#---主要用来区别不同的对象,当然你也可以用self.setObjectName()---#
self.name = arg.name
...
def dotask(self,arg):
...
#---任务结束时,发射信号停止线程---#
self.finished.emit()

#----------------步骤2,维护一个线程池,管理程序内的线程--------------#
class ThreadManager(qt.QObject):
def __init__(self):
super(ThreadManager,self).__init__()
#---获取最优线程数---#
self.maxThreads = qt.QThreadPool.globalInstance().maxThreadCount()
#---定义一个空闲列表和一个忙碌列表,空闲的线程可以被获取---#
self.freeList = []
self.currentThreads = 0
self.busyList = []
for i in range(self.maxThreads):
thread = qt.QThread()
self.freeList.append(thread)
#---申请获取空闲线程---#
def requireThread(self):
self.checkThreads()
if self.currentThreads < self.maxThreads:
thread = self.freeList.pop()
self.busyList.append(thread)
self.currentThreads = self.currentThreads+1
return thread
else:
return False
#---检查线程,如果忙碌线程已经完毕,则归到空闲线程列表---#
def checkThreads(self):
for thread in self.busyList:
if not thread.isRunning():
self.freeList.append(thread)
self.busyList.remove(thread)
self.currentThreads = self.currentThreads - 1

#---退出时,记得结束线程---#
def __del__(self):
for thread in self.busyList:
thread.quit()
thread.wait()
for thread in self.freeList:
thread.quit()
thread.wait()

#--------------步骤3,创建一个总的程序管理类------------------------#
class mainController(qt.QObject):
def __init__(self,arg):
super(mainController,self).__init__()
...
#---线程管理---#
self.threadManager = ThreadManager()
#---任务队列---#
self.taskQueue = []
#---正在运行的任务,用字典方便查询、删除等操作---#
self.runningDict = {}

#---创建任务,主要对任务进行一些诸如绑定信号槽等操作---#
def createTask(self,arg):
task = OP(arg)
#---进行一些task的信号槽绑定工作,主要用来跨线程传递消息---#
...
thread = self.threadManager.requireThread()
if thread:
#---线程申请成功---#
self.runningDict[task.name] = task
task.moveToThread(thread)
task.finished.connect(thread.quit)
thread.started.connect(task.dotask)
thread.start()
else:
#---线程申请失败---#
self.taskQueue.append(task)

#---当运行任务结束,清理runningList,执行等待队列中的任务---#
def  onTaskFinished(self,arg):
del runningDict[arg.name]
thread = self.threadManager.requireThread()
if thread and self.taskQueue.__len__()>0:
#---线程申请成功,并且任务队列非空---#
task = self.taskQueue.pop(0)
self.runningDict[task.name] = task
task.moveToThread(thread)
task.finished.connect(thread.quit)
thread.started.connect(task.dotask)
thread.start()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息