PySide6.QtCore.QThread

class QThread

QThread 类提供了一种平台无关的方式来管理线程。更多

PySide6.QtCore.QThread 的继承图

概要

方法

虚拟方法

插槽

信号

静态函数

注意

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

详细描述

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

一个 QThread 对象管理程序中的一个控制线程。QThreads 在 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():

Worker的槽中的代码将在单独的线程中执行。然而,您可以自由地将Worker的槽连接到任何线程中的任何对象的任何信号。由于一种称为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()

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

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

与排队的槽或调用的方法不同,直接在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() 函数,不如考虑使用 QChronoTimer

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

要选择线程的名称(例如在Linux上通过命令ps -L识别),你可以在启动线程之前调用setObjectName()。如果你不调用setObjectName(),线程的名称将是线程对象运行时类型的类名(例如,在Mandelbrot示例中为"RenderThread",因为这是QThread子类的名称)。请注意,目前在Windows的发布版本中不可用。

另请参阅

QThreadStorage Mandelbrot 使用信号量的生产者和消费者 使用等待条件的生产者和消费者

class Priority

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

常量

描述

QThread.IdlePriority

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

QThread.LowestPriority

比LowPriority更少被调度。

QThread.LowPriority

调度频率低于NormalPriority。

QThread.NormalPriority

操作系统的默认优先级。

QThread.HighPriority

比NormalPriority更频繁地调度。

QThread.HighestPriority

比高优先级更频繁地调度。

QThread.TimeCriticalPriority

尽可能频繁地调度。

QThread.InheritPriority

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

__init__([parent=None])
Parameters:

父对象QObject

构造一个新的QThread来管理一个新线程。parent拥有QThread的所有权。线程在调用start()之前不会开始执行。

另请参阅

start()

static currentThread()
Return type:

QThread

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

eventDispatcher()
Return type:

QAbstractEventDispatcher

返回指向线程的事件分发器对象的指针。如果线程没有事件分发器,此函数返回None

另请参阅

setEventDispatcher()

exec()
Return type:

整数

进入事件循环并等待直到调用exit(),返回传递给exit()的值。如果通过quit()调用exit(),则返回的值为0。

此函数旨在从run()内部调用。必须调用此函数以启动事件处理。

注意

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

另请参阅

quit() exit()

exec_()
Return type:

整数

exit([retcode=0])
Parameters:

retcode – int

告诉线程的事件循环以返回代码退出。

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

按照惯例,returnCode 为 0 表示成功,任何非零值表示错误。

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

在这个线程中,直到再次调用exec()之前,不会再启动任何QEventLoops。如果exec()中的事件循环没有运行,那么下一次调用exec()也会立即返回。

另请参阅

quit() QEventLoop

finished()

此信号在关联线程即将完成执行时发出。

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

注意

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

另请参阅

started()

static idealThreadCount()
Return type:

整数

返回此进程可以并行运行的最佳线程数。这是通过查询此进程可用的逻辑处理器数量(如果此操作系统支持)或系统中逻辑处理器的总数来完成的。如果无法确定这两个值,则此函数返回1。

注意

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

注意

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

isCurrentThread()
Return type:

布尔

如果此线程是currentThread,则返回true。

另请参阅

currentThreadId()

isFinished()
Return type:

布尔

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

另请参阅

isRunning()

isInterruptionRequested()
Return type:

布尔

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

此函数可用于使长时间运行的任务能够干净地中断。从不检查或处理此函数返回的值是安全的,但建议在长时间运行的函数中定期执行此操作。注意不要过于频繁地调用它,以保持开销较低。

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

注意

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

static isMainThread()
Return type:

布尔

返回当前执行的线程是否是主线程。

主线程是创建QCoreApplication的线程。这通常是调用main()函数的线程,但不一定如此。它是处理GUI事件的线程,并且可以在其中创建图形对象(QWindow, QWidget)。

isRunning()
Return type:

布尔

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

另请参阅

isFinished()

loopLevel()
Return type:

整数

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

注意

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

static msleep(msecs)
Parameters:

msecs – 整数

这是一个重载函数,等同于调用:

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

注意

此函数不保证准确性。在重负载条件下,应用程序可能会睡眠超过msecs。某些操作系统可能会将msecs四舍五入到10毫秒或15毫秒。

另请参阅

sleep() usleep()

priority()
Return type:

优先级

返回正在运行的线程的优先级。如果线程没有运行,此函数返回 InheritPriority

quit()

告诉线程的事件循环以返回代码0(成功)退出。相当于调用exit (0)。

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

另请参阅

exit() QEventLoop

requestInterruption()

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

run()

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

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

另请参阅

start() wait()

setEventDispatcher(eventDispatcher)
Parameters:

eventDispatcherQAbstractEventDispatcher

将线程的事件调度器设置为eventDispatcher。这只有在尚未为线程安装事件调度器时才可能实现。

QCoreApplication被实例化时,主线程的事件分发器会自动创建,并且在辅助线程的start()时也会创建。

此方法获取对象的所有权。

另请参阅

eventDispatcher()

setPriority(priority)
Parameters:

优先级Priority

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

priority 参数可以是 QThread::Priority 枚举中的任何值,除了 InheritPriority

priority 参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统上(例如在 Linux 上,详见 http://linux.die.net/man/2/sched_setscheduler),priority 将被忽略。

setStackSize(stackSize)
Parameters:

stackSize – int

设置线程的堆栈大小为stackSize。如果stackSize为零,操作系统或运行时将选择一个默认值。否则,线程的堆栈大小将设置为提供的值(可能会向上或向下取整)。

在大多数操作系统上,分配给栈服务的内存量最初会小于stackSize,并且会随着线程使用栈而增长。此参数设置它允许增长到的最大大小(即,它设置栈允许占用的虚拟内存空间的大小)。

此函数只能在线程启动之前调用。

警告

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

另请参阅

stackSize()

static setTerminationEnabled([enabled=true])
Parameters:

enabled – 布尔值

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

enabled为false时,终止功能被禁用。未来调用terminate()将立即返回而不产生效果。相反,终止将被推迟,直到启用终止功能。

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

另请参阅

terminate()

static sleep(secs)
Parameters:

秒数 – 整数

强制当前线程休眠 secs 秒。

这是一个重载函数,等同于调用:

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

另请参阅

msleep() usleep()

stackSize()
Return type:

整数

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

另请参阅

setStackSize()

start([priority=QThread.Priority.InheritPriority])
Parameters:

优先级Priority

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

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

另请参阅

run() terminate()

started()

当关联线程开始执行时,会发出此信号,因此任何连接到它的槽可能会通过排队调用来调用。尽管事件可能在调用run()之前已经发布,但信号的任何跨线程传递可能仍然处于挂起状态。

另请参阅

run() finished()

terminate()

终止线程的执行。线程可能会立即终止,也可能不会立即终止,这取决于操作系统的调度策略。在terminate()之后使用wait(),以确保线程终止。

当线程终止时,所有等待该线程完成的线程将被唤醒。

警告

此函数是危险的,不鼓励使用。线程可以在其代码路径的任何点被终止。线程在修改数据时可能会被终止。线程没有机会自行清理、解锁持有的互斥锁等。简而言之,只有在绝对必要时才使用此函数。

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

static usleep(usecs)
Parameters:

usecs – int

这是一个重载函数,等同于调用:

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

注意

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

另请参阅

sleep() msleep()

wait([deadline=QDeadlineTimer(QDeadlineTimer.Forever)])
Parameters:

截止日期QDeadlineTimer

Return type:

布尔

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

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

  • 达到了deadline。如果达到了截止日期,此函数将返回false。

设置为QDeadlineTimer::Forever(默认值)的截止时间计时器将永远不会超时:在这种情况下,函数只有在线程从run()返回时才会返回,或者如果线程尚未启动。

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

另请参阅

sleep() terminate()

wait(time)
Parameters:

时间 – int

Return type:

布尔

这是一个重载函数。

time 是等待的时间,以毫秒为单位。如果 time 是 ULONG_MAX,那么等待将永远不会超时。

static yieldCurrentThread()

将当前线程的执行权让给另一个可运行的线程(如果有的话)。请注意,操作系统决定切换到哪个线程。