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

前言
本教程适合像我一样接触多线程不深的新手,也适合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()

猜你喜欢

转载自blog.csdn.net/qq_16952303/article/details/79775097