今天,继续研究关于QtCoreApplication的构造函数问题。
QCoreApplication::self = this;
该类保存了自身的指针,是静态方法,同时是私有成员,刚开始的时候以为是单例模式,后来发现好像也不是。
不过跟之前的断言放在一起,就发现了其真正的意图。
Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
该断言保证了QCoreApplication对象只能被创建一次,同时又采用了静态方法的方式将对象提供出来。现在知道了,原来这是一个变形的单例设计模式。
#ifndef QT_NO_THREAD
QThread::initialize();
#endif
这里的定义可以看出来,在控制台应用程序中,可以选择采用多线程方式,或者单线程方式。但是具体的线程实现,以后再做研究。
// use the event dispatcher created by the app programmer (if any)
if (!QCoreApplicationPrivate::eventDispatcher)
QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
// otherwise we create one
if (!QCoreApplicationPrivate::eventDispatcher)
d->createEventDispatcher();
Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
if (!QCoreApplicationPrivate::eventDispatcher->parent())
QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
这里通过应用程序创建并使用事件调度程序。如果线程中存在了调度程序对象,则赋值指针,否则得花,创建事件调度程序。
这里如果创建失败,程序会终止。
看来,我们需要对QThrad进行一步的研究了,否则无法解释接下来的问题了。
我们查看下QThread的initialize方法。
if (qt_global_mutexpool)
return;
qt_global_mutexpool = QMutexPool::instance();
#if defined (Q_OS_WIN)
qt_create_tls();
#endif
这里可以看到,首先程序判定互斥池是否创建,如果全局的互斥池指针已经创建,则说明线程已经进行过初始化,直接返回。否则得花,进行对QmutexPool类进行实例化。现在发现,原来好多类的设计都采用了单例模式。
在QMutexPool的instance方法中,返回了全局的互斥池,这里应该是为了保证线程安全用的。调用的函数是:globalMutexPool(),但是该函数是以宏定义的形式进行实现的,比较隐蔽。
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) /
Q_GLOBAL_STATIC_INIT(TYPE, NAME); /
static TYPE *NAME() /
{ /
if (!this_##NAME.pointer && !this_##NAME.destroyed) { /
TYPE *x = new TYPE ARGS; /
if (!this_##NAME.pointer.testAndSetOrdered(0, x)) /
delete x; /
else /
static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); /
} /
return this_##NAME.pointer; /
}
#define Q_GLOBAL_STATIC_INIT(TYPE, NAME) /
static QGlobalStatic<TYPE > this_##NAME = { Q_BASIC_ATOMIC_INITIALIZER(0), false }
发现宏Q_BASIC_ATOMIC_INITIALIZER没有找到,只能理解为一个原子整形数据,具体的实现就不清楚了,我们将宏替换掉,看是一个什么样的效果呢?
Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true))
替换为
static QGlobalStatic< QMutexPool > this_globalMutexPool = { Q_BASIC_ATOMIC_INITIALIZER(0), false }
static QMutexPool * globalMutexPool () /
{ /
if (!this_ globalMutexPool.pointer && !this_ globalMutexPool.destroyed) { /
QMutexPool *x = new QMutexPool ARGS; /
if (!this_globalMutexPool.pointer.testAndSetOrdered(0, x)) /
delete x; /
else /
static QGlobalStaticDeleter< QMutexPool > cleanup(this_ QMutexPool); /
} /
return this_ globalMutexPool.pointer; /
}
这就是替换后的globalMutexPool()函数的实现,该函数的主要功能就是返回一个线程安全的函数全局互斥池对象的指针。
接下来我们可以看下事件调度者的实现问题。在Windows系统下,进行了如下定义:
#elif defined(Q_OS_WIN)
eventDispatcher = new QEventDispatcherWin32(q);
这里创建了Win32下的事件调度者对象,看样子,是一个很庞大内容了,今天就到这里还有其他事情要做,明天去看关于事件调度类的具体细节。
2009年10月14日星期三 23:33