为何只能在其关联的线程内启动timer?(Qt会检查一致性,否则就不执行)

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为何只能在其关联的线程内启动timer?(Qt会检查一致性,否则就不执行)相关的知识,希望对你有一定的参考价值。

为何只能在其关联的线程内启动timer?

QTimer源码分析(以Windows下实现为例) 一文中,我们谈到:

QTimer的是通过QObject的timerEvent()实现的,开启和关闭定时器是通过QObject的startTimer()和killTimer完成的。

startTimer最终调用对象关联线程的eventDispatcher来注册定时器:

int QObject::startTimer(int interval)
{
    Q_D(QObject);
    return d->threadData->eventDispatcher->registerTimer(interval, this);

在Win32平台下:

void QEventDispatcherWin32::registerTimer(int timerId, int interval, QObject *object)
{
    if (timerId < 1 || interval < 0 || !object) {
        qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
        return;
    } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::startTimer: timers cannot be started from another thread");
        return;
    }
...

Linux平台下:

void QEventDispatcherGlib::registerTimer(int timerId, int interval, QObject *object)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1 || interval < 0 || !object) {
        qWarning("QEventDispatcherGlib::registerTimer: invalid arguments");
        return;
    } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::startTimer: timers cannot be started from another thread");
        return;
    }
...

在这两个平台下,它都会检查当前线程和dispatcher的线程是否一致。不一致则直接返回。

为什么要这么设计。我不太清楚。或许是因为:注册定时器要用到回调函数,而回调函数需要在注册的线程执行(fix me)。

 

http://blog.csdn.net/lynfam/article/details/7081545

以上是关于为何只能在其关联的线程内启动timer?(Qt会检查一致性,否则就不执行)的主要内容,如果未能解决你的问题,请参考以下文章

Qt5 自定义线程下使用定时器

Qt 线程关联和 moveToThread 的问题

Qt 进程和线程之二:启动线程

QTimer 线程亲和性

为何mysql中总是有sleep线程?怎样产生的

关于Qt在新线程中创建定时器的问题