class QThread#

QThread 类提供了跨平台的多线程管理方式。更多...

Inheritance diagram of PySide6.QtCore.QThread

摘要#

方法#

虚方法#

#

信号#

静态函数#

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对片段翻译的贡献。如果您发现翻译中的问题,也可以通过在https:/bugreports.qt.io/projects/PYSIDE创建工单的方式告知我们。

详细描述#

警告

本节包含了自动从C++转换为Python的代码片段,可能包含错误。

一个QThread对象管理程序中的一个线程控制。QThread从run()开始执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。

您可以通过使用moveToThread()将工作对象移动到线程中来使用它们。

class Worker(QObject):

    Q_OBJECT
# public slots
    def doWork(parameter):
        result = QString()
        /* ... here is the expensive or blocking operation ... */
        resultReady.emit(result)

# signals
    def resultReady(result):

class Controller(QObject):

    Q_OBJECT
    workerThread = QThread()
# public
    Controller() {
        worker = Worker()
        worker.moveToThread(workerThread)
        workerThread.finished.connect(worker.deleteLater)
        self.operate.connect(worker.doWork)
        worker.resultReady.connect(self.handleResults)
        workerThread.start()

    ~Controller() {
        workerThread.quit()
        workerThread.wait()

# public slots
    def handleResults():
# signals
    def operate():

工件的槽中的代码将在一个单独的线程中执行。然而,您可以将工件的槽连接到任何对象的任何信号中,在任意的线程中。由于存在一种称为queued connections的机制,因此在不同线程之间连接信号和槽是安全的。

使代码在单独的线程中运行的另一种方式是,通过继承QThread并重写run()来实现。例如

class WorkerThread(QThread):

    Q_OBJECT
    def run():
        result = QString()
        /* ... here is the expensive or blocking operation ... */
        resultReady.emit(result)

# signals
    def resultReady(s):

def startWorkInAThread(self):

    workerThread = WorkerThread(self)
    workerThread.resultReady.connect(self.handleResults)
    workerThread.finished.connect(workerThread.deleteLater)
    workerThread.start()

在这个例子中,线程将在run函数返回后退出。除非您调用exec(),否则线程中不会运行任何事件循环。

重要的是要记住,QThread实例lives in创建它的旧线程中,而不是在调用run() 的新线程中。这意味着所有QThread的队列槽和invoked methods都将在这个旧线程中执行。因此,希望在新线程中调用槽的开发者必须使用工作对象方法;不应直接在工作对象继承的子类中实现新槽。

与排队槽位或调用的方法不同,直接在QThread对象上调用的方法将在调用方法的线程中执行。当继承QThread时,请注意构造函数在旧线程中执行,而run()在新的线程中执行。如果从这两个函数中访问成员变量,则变量将在两个不同的线程中访问。请检查这样做是否安全。

注意

在跨不同线程交互对象时必须小心。一般来说,函数只能从创建QThread对象的线程本身调用(例如:setPriority()),除非文档说明其他情况。请参阅同步线程的详细信息。

管理线程#

QThread将通过信号通知您线程何时started()finished(),或者您可以使用isFinished()isRunning()来查询线程的状态。

您可以通过调用exit()quit()来停止线程。在极端情况下,您可能想强迫terminate()正在执行的线程。但是,这样做是危险的,不推荐。请阅读terminate()setTerminationEnabled()的文档,获取详细信息。

当一个线程结束时,您通常希望释放在该线程中存在的对象。为此,将finished()信号连接到deleteLater()

使用wait()来阻塞调用线程,直到另一个线程完成执行(或者直到经过指定的时间)。

QThread 还提供静态、平台无关的睡眠函数: sleep()msleep() ,以及 usleep() 分别提供一秒钟、毫秒和微秒的分辨率。

注意

wait()sleep() 函数通常是不必要的,因为 Qt 是一个事件驱动的框架。代替 wait() ,可以考虑监听 finished() 信号。代替 sleep() 函数,考虑使用 QTimer .

currentThreadId()currentThread() 静态函数返回当前正在执行的线程的标识符。前者返回线程的平台特定 ID;后者返回一个 QThread 指针。

为了选择您的线程将被赋予的名称(例如,在 Linux 中由命令 ps -L 识别),您可以在启动线程之前调用 setObjectName() 。如果您不调用 setObjectName() ,您的线程名称将是线程对象的运行时类型的类名(例如,在 Mandelbrot 示例中的 "RenderThread",因为这是 QThread 子类的名称)。注意,这目前在 Windows 的发行版构建中不可用。

class Priority#

此枚举类型指示操作系统应如何调度新创建的线程。

常量

描述

QThread.IdlePriority

仅在没有任何其他线程运行时才会调度。

QThread LowestPriority

调度频率低于LowPriority。

QThread LowPriority

调度频率低于NormalPriority。

QThread NormalPriority

操作系统的默认优先级。

QThread HighPriority

调度频率高于NormalPriority。

QThread HighestPriority

调度频率高于HighPriority。

QThread TimeCriticalPriority

尽可能频繁地调度。

QThread InheritPriority

使用创建线程相同的优先级。这是默认设置。

__init__([parent=None])#
参数:

parentQObject

构建一个新的 QThread 以管理一个新的线程。父对象将拥有 QThread 的所有权。线程不会开始执行,直到调用 start()

另请参阅

start()

static currentThread()#
返回类型:

QThread

返回一个指向当前正在执行线程的 QThread 的指针。

eventDispatcher()#
返回类型:

QAbstractEventDispatcher

返回指向线程事件调度程序的指针。如果线程没有事件调度程序,此函数返回 None

另请参阅

setEventDispatcher()

exec()#
返回类型:

int

进入事件循环并等待直到调用 exit() ,返回传递给 exit() 的值。调用 quit() 时,返回的值是 0。

此函数应在 run() 内部调用。调用此函数是开始事件处理所必需的。

注意

这只能在线程内部调用,即它当前是当前线程时。

另请参阅

quit() exit()

exec_()#
返回类型:

int

exit([retcode=0])#
参数:

retcode – int

通知线程的事件循环以退出的形式结束。

在调用此函数后,线程离开事件循环并从对exec() 的调用中返回。该exec() 函数返回 returnCode

按照惯例,返回码为 0 表示成功,任何非零值都表示错误。

注意,与同名的 C 库函数不同,此函数 确实 返回给调用者 – 停止的是事件处理。

在再次调用 exec() 之前,将不会在此线程中再开始任何 QEventLoops。如果 exec() 中的事件循环没有运行,下一个对 exec() 的调用也将立即返回。

另请参阅

quit() QEventLoop

finished()#

此信号在相关的线程在执行完毕之前发出。

在此信号发出时,事件循环已停止运行。线程不会处理更多事件,除非是延迟删除事件。可以将此信号连接到 deleteLater() ,以释放该线程中的对象。

注意

如果使用 terminate() 终止了相关的线程,那么从哪个线程发出此信号是未定义的。

另请参阅

started()

静态 idealThreadCount()#
返回类型:

int

返回此进程能够并行运行的理想线程数。这是通过查询此进程可用的逻辑处理器数量(如果此操作系统支持)或系统逻辑处理器的总数来实现的。如果无法确定这两个值中的任何一个,则该函数返回 1。

注意

在支持将线程的亲和力设置为所有逻辑处理器子集的操作系统上,此函数返回的值可能在线程之间以及随时间变化。

注意

在支持CPU热插拔和热拔插的操作系统上,此函数返回的值也可能会随时间改变(并且请注意,CPU可以通过软件进行打开和关闭,而无需进行物理或硬件上的更改)。

isFinished()#
返回类型:

bool

如果线程已完成则返回 true;否则返回 false

另请参阅

isRunning()

isInterruptionRequested()#
返回类型:

bool

如果应停止在此线程上运行的任务,则返回 true。可以通过 requestInterruption() 请求中断。

此函数可用于使长时间运行的任务干净地可中断。不建议在长时间运行的函数中频繁检查此函数返回的值,但对于这种情况是有好处的。请注意,不要过度调用它,以保持开销低。

void long_task() {
     forever {
        if ( QThread::currentThread()->isInterruptionRequested() ) {
            return;
        }
    }
}

注意

这只能在线程内部调用,即它当前是当前线程时。

isRunning()#
返回类型:

bool

如果线程正在运行则返回 true;否则返回 false

另请参阅

isFinished()

loopLevel()#
返回类型:

int

返回线程当前的事件循环级别。

注意

这只能在线程内部调用,即它当前是当前线程时。

static msleep(arg__1)#
参数:

arg__1 – int

这是一个重载函数,相当于调用

QThread::sleep(std::chrono::milliseconds{msecs});

注意

该函数不保证准确性。在负载较高的情况下,应用程序的休眠时间可能超过 msecs。某些操作系统可能将 msecs 四舍五入到 10 毫秒或 15 毫秒。

另请参阅

sleep() usleep()

priority()#
返回类型:

优先级

返回运行线程的优先级。如果线程未运行,则此函数返回 InheritPriority

quit()#

将线程的事件循环退出并返回代码0(成功)。等同于调用exit(0)。

如果线程没有事件循环,此函数不执行任何操作。

另请参阅

exit() - QEventLoop

requestInterruption()#

请求中断线程。该请求是建议性的,由在线程上运行的代码决定是否以及如何对此类请求做出反应。此函数不会停止线程上运行的任何事件循环,也不会以任何方式终止它。

run()#

线程的起点。在调用start()后,新创建的线程将调用此函数。默认实现只是调用exec()

您可以通过重新实现此函数来简化高级线程管理。从该方法返回将结束线程的执行。

另请参阅

start() - wait()

setEventDispatcher(eventDispatcher)#
参数:

eventDispatcher - QAbstractEventDispatcher

为线程设置事件派送器为eventDispatcher。只有当线程尚未安装事件派送器时,才能进行此操作。

当实例化QCoreApplication时,为主线程自动创建事件派送器,并在start()中为辅助线程创建。

此方法将获取对对象的拥有权。

另请参阅

eventDispatcher()

setPriority(priority)#
参数:

优先级Priority

这个函数将该运行的线程的优先级设置为 priority。如果线程没有运行,此函数将不执行任何操作并立即返回。使用 start() 以特定优先级启动线程。

priority 参数可以是 QThread::Priority 枚举中的任何值,但不能是 InheritPriority

priority 参数的影响取决于操作系统的调度策略。特别是,在不支持线程优先级的系统上(如Linux,更多信息请参见 http://linux.die.net/man/2/sched_setscheduler)将忽略 priority

另请参阅

Priority priority() start()

setStackSize(stackSize)#
参数:

stackSize – int

将线程的最大堆栈大小设置为 stackSize。如果 stackSize 大于零,则最大堆栈大小设置为 stackSize 字节,否则由操作系统自动确定最大堆栈大小。

警告

大多数操作系统为线程堆栈大小设置最小和最大限制。如果堆栈大小超出这些限制,则线程将无法启动。

另请参阅

stackSize()

static setTerminationEnabled([enabled=true])#
参数:

enabled – bool

根据 enabled 参数启用或禁用当前线程的终止。线程必须由 QThread 启动。

如果 enabled 为 false,则禁用终止。对 terminate() 的将来调用将立即返回,不产生任何效果。相反,终止将被延迟,直到启用终止。

enabled 设置为 true 时,终止功能被启用。未来对 terminate() 的调用将正常终止线程。如果终止已被推迟(即 terminate() 被调用时终止被禁用),此函数将立即终止调用线程。请注意,在这种情况下此函数不会返回。

另请参阅

terminate()

静态 sleep(arg__1)#
参数:

arg__1 – int

强制当前线程休眠 secs 秒。

这是一个重载函数,相当于调用

QThread::sleep(std::chrono::seconds{secs});

另请参阅

msleep() usleep()

stackSize()#
返回类型:

int

返回线程的最大栈大小(如果使用 setStackSize() 设置),否则返回零。

另请参阅

setStackSize()

start([priority=QThread.Priority.InheritPriority])#
参数:

优先级Priority

通过调用 run() 开始线程的执行。操作系统将根据 priority 参数调度线程。如果线程已经在运行,此函数将不做任何事情。

priority 参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统(如 Linux,更多信息请参阅 sched_setscheduler 文档)上,将忽略 priority

另请参阅

run() terminate()

started()#

当关联的线程开始执行且在调用 run() 函数之前发射此信号。

另请参阅

finished()

terminate()#

终止线程的执行。线程是否立即终止取决于操作系统的调度策略。请在terminate()之后使用wait(),以确保。

当线程终止时,所有等待该线程结束的线程都将被唤醒。

警告

此功能非常危险,不建议使用。线程可能在代码路径的任何点被终止。线程可能在修改数据时被终止。没有机会让线程自行清理,解锁任何持有的互斥锁等。简而言之,仅当绝对必要时才使用此函数。

可以通过调用setTerminationEnabled()来显式启用或禁用终止。当禁用终止时调用此函数会导致终止被推迟,直到重新启用终止。有关更多信息,请参阅setTerminationEnabled()的文档。

静态 usleep(arg__1)#
参数:

arg__1 – int

这是一个重载函数,相当于调用

QThread::sleep(std::chrono::microseconds{secs});

注意

此函数不保证准确性。在负载较高的条件下,应用程序可能睡眠时间超过usecs。某些操作系统可能将usecs四舍五入到10毫秒或15毫秒;在Windows上,它将被四舍五入到1毫秒的整数倍。

另请参阅

sleep() msleep()

wait([deadline=QDeadlineTimer(QDeadlineTimer.Forever)])#
参数:

超时时间QDeadlineTimer

返回类型:

bool

阻塞线程,直到满足以下任一条件

  • 与该QThread对象关联的线程已结束执行(即当它从run()返回)。如果线程已结束,此函数将返回true。如果线程尚未启动,它也将返回true。

  • 达到超时时间。如果达到超时,此函数将返回false。

将超时计时器设置为QDeadlineTimer::Forever(默认)将永远不会超时:在这种情况下,仅在线程从run()返回或线程尚未启动时,函数才返回。

这提供了与POSIX pthread_join()函数类似的功能。

另请参阅

sleep() terminate()

wait(时间)
参数:

时间 – int

返回类型:

bool

这是一个重载函数。

时间 是等待的毫秒数。如果 时间 是 ULONG_MAX,则等待永远不会超时。

静态yieldCurrentThread()#

如果存在可运行线程,则将当前线程的执行权让给其他可运行线程。请注意,操作系统决定切换到哪个线程。