多线程的概念
在采用多线程编程技术的程序中,多个任务由不同的线程去执行,不同线程各自占用一段CPU时间,即使线程任务还没完成,也会让出CPU时间给其他线程去执行。这样从用户的角度来看,好像几个任务是同时进行的,至少界面上能得到及时更新了,大大改善了用户的体验,提高了软件的响应速度和友好度。
对于同一进程的线程来说,它们共享该进程的地址空间,可以访问相同的数据。通过数据共享方式使得线程之间的通信比进程之间的通信更高效和方便。
现代操作系统大多支持多线程概念,每个进程至少有一个线程,所以即使没有使用多线程编程技术,进程也含有一个主线程,所以也可以说,CPU中执行的是线程,线程是程序的最小执行单位,是操作系统分配CPU时间的最小实体。一个进程的执行说到底是从主线程开始的,如果需要在程序任何地方开辟新的线程,其他线程都是由主线程创建的。一个进程正在运行,也可以说是一个进程中的某个线程正在运行。一个进程的所有线程共享该进程的公共资源,比如虚拟地址空间、全局变量等。每个线程也可以拥有自己的私有资源,如堆栈、在堆栈中定义的静态变量和动态变量、CPU寄存器的状态等。
线程总是在某个进程环境中创建的,并且会在这个进程内部销毁。线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时,该进程所产生的线程都会被强制退出并清除。线程可与属于同一进程的其他线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和线程栈,线程栈用于维护线程在执行代码时需要的所有函数参数和局部变量。)
在程序设计中,为了不影响主程序的执行,常常把耗时操作放到一个单独的线程中执行。Qt对多线程操作有着完整的支持,通过继承QThread并重写run()方法的方式实现多线程代码的编写。针对多线程之间的同步与互斥问题,Qt还提供了QMutex、QReadWriteLock、QwaitCondition、QSemaphore等多个类来实现。
Qt的多线程创建一般有两种方法,一是继承QThread并重写run()函数,二是继承QObject,利用信号槽调用相关函数。第一种方法,在新的线程中只能实现run()函数中的内容,而第二种可以通过movetothread()随意调用自己想用的方法,也可以只用一个类实现多个线程共同工作。
QThread
实现多线程时:首先要创建一个线程类,线程类中设置自定义信号,通过emit将信号发出(传递了参数),再由UI界面的槽函数接受,执行相关操作。
引用自文章:[ PyQt入门教程 ] PyQt5中多线程模块QThread使用方法
# -*- coding: utf-8 -*-
import sys
import time
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow
from QThread_Example_UI import Ui_Form
class MyMainForm(QMainWindow, Ui_Form):
def __init__(self, parent=None):
super(MyMainForm, self).__init__(parent)
self.setupUi(self)
# 实例化线程对象
self.work = WorkThread()
self.runButton.clicked.connect(self.execute)
def