为何只能在其关联的线程内启动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

时间: 2024-12-13 05:59:22

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

ASP.net如何保证EF操作类线程内唯一

说到线程内唯一,肯定会想到单例模式,但是如果多用户访问网站就会出现问题.ASP.net中有两种方法可以保证EF操作类线程内唯一(目前只会这两种,以后有好的方法再添加): 1.httpcontext(实现原理也是通过数据槽callcontext) 将EF操作类通过键值对方法保存在HttpContext.Current.Items["key"],封装成方法直接调用 2.callcontext public static DbContext CreateDbContext() { DbCon

.Net普通三层-&gt;工厂模式-&gt;线程内唯一+单元工作模式-&gt;WebService分布式三层

在软件世界分层的思想无处不在 主要是为了提高软件系统的维护性,扩展性,复用性和解耦等 软件的三层构架是一种最基本的分层思想的体现 结构图大体如下: 如此一来,开发人员可以只关注其中一层,而无需关心下一层是如何实现的 但是最基本的三层构架在软件系统中很明显是不够用的 因为它带来优点的同时也带着许多缺点,比如耦合性高,经常出现修改某一层的代码另外一层也要随之大幅度整顿 而且当需求发生改变的时候,如:原先开发的时候使用mssql数据库,而现在又要求更换成mysql数据库 更换Dal层会导致Bll层也要

qt数据库多线程问题的解决(QSqlDatabase只能在创建它的线程中使用)

Qt数据库由QSqlDatabase::addDatabase()生成的QSqlDatabase只能在创建它的线程中使用, 在多线程中共用连接或者在另外一个线程中创建query都是不支持的几乎国内没有文章提到这个问题,这几天在做数据库压力测试时遇到了 假设有如下代码: bool openDatabase() { QSqlDatabase db; QString connectionName = "sqlite"; db = QSqlDatabase::addDatabase("

EF上下文对象创建之线程内唯一

在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,那么会造成数据混乱,每次创建的对象执行相应的数据库操作,此同时,其他的EF对象内获得的数据可能已经是“过期”的了.即这个数据已经变动过.这就是数据混乱,为了解决这个问题,关键就是对象的创建问题. 这里首先想到单例模式,不过在这里,不适合用,原因是使用单例模式,会使EF对象得不到及时的资源释放. 第二种方式即保证在线程内对象唯一,如何保证呢,通过微软ASP机制的HttpContext对象,这个对象在线程中是唯一的,所以我们在Htt

EF上下文对象线程内唯一性与优化

在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用了多个dal层的方法,交互数据库多次,这样效率会低一些,而且在使用EF的情况下,我们通常把SaveChange这个方法提到业务逻辑层(下文中会提到),不保证同一个业务逻辑使用的是同一个上下文对象,事务,工作单元模式将无法实现.而且可能造成数据混乱,每次创建的对象执行相应的数据库操作,与此同时,同一次

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装  (5):前台Jquery easyUI实现   (6):EF上下文实例管理   (7):DBSession的封装 前言:通过上篇博客我们完成了对DbSession的代码编写,DbSession就相

C# 如何保证对象线程内唯一:数据槽(CallContext)

如果说,一个对象保证全局唯一,大家肯定会想到一个经典的设计模式:单例模式,如果要使用的对象必须是线程内唯一的呢? 数据槽:CallContext,ok看下msdn对callcontent的解释. CallContext 是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽.数据槽不在其他逻辑线程上的调用上下文之间共享.当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中. 也就是说,当前线程对对象进行储存到线程本地

.Net普通三层 到 工厂模式-&gt;线程内唯一+单元工作模式-&gt;WebService分布式三层

在软件世界分层的思想无处不在 主要是为了提高软件系统的维护性,扩展性,复用性和解耦等 软件的三层构架是一种最基本的分层思想的体现 结构图大体如下: 如此一来,开发人员可以只关注其中一层,而无需关心下一层是如何实现的 但是最基本的三层构架在软件系统中很明显是不够用的 因为它带来优点的同时也带着许多缺点,比如耦合性高,经常出现修改某一层的代码另外一层也要随之大幅度整顿 而且当需求发生改变的时候,如:原先开发的时候使用mssql数据库,而现在又要求更换成mysql数据库 更换Dal层会导致Bll层也要

一个线程可以拿到多个锁标记,一个对象最多只能将monitor给一个线程

当用Synchronized修饰某个方法的时候,表示该方法都对当前对象加锁. 给方法加Synchronized和用Synchronized修饰对象的效果是一致的. 一个线程可以拿到多个锁标记,一个对象最多只能将monitor给一个线程. Synchronized是以牺牲程序运行的效率为代价的,因此应该尽量控制互斥代码块的范围. 方法的Synchronized特性本身不会被继承,只能覆盖. 线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池. 每个对象都有自己的一个锁池的空间