当前位置: 首页 > news >正文

网站开发优秀毕业论文网站推广的具体方案

网站开发优秀毕业论文,网站推广的具体方案,网站制作专业的公司哪家好,专业做旅游网站先说重点,先了解几个重要的概念, 事件调度器,该调度器的具体实现与操作系统相关,不同的操作系统具有不同的实现,例如linux系统下该调度器的实现为QEventDispatcherUNIX,而window下的他们的实现为QEventDis…

先说重点,先了解几个重要的概念,

  • 事件调度器,该调度器的具体实现与操作系统相关,不同的操作系统具有不同的实现,例如linux系统下该调度器的实现为QEventDispatcherUNIX,而window下的他们的实现为QEventDispatcherWin32,他们的目录是QTDIR/5.15.2/Src/qtbase/src/corelib/kernel目录下寻找即可。该调度器实现了事件循环的核心功能。不同操作系统的事件调度器他们的基类是同一个QAbstractEventDispatcher。
  • threadData,这里就称它为线程数据吧,每个QObject都有这样一个数据成员,从这里可以看出每个QObject对象都是线程相关的。threadData包含了该对象所属线程的相关信息,其中包含了该线程的事件队列等,该数据成员可以通过qobject::movetoThread来实现转移。
  • 每个线程可以启动多个事件循环(QEventLoop),但是所有的QEventLoop共享同一个事件调度器,所以在一个线程中即使启动多个事件,最终的事件循环中的事件调度器是同一个。
  • 事件循环的主要功能:我自身的理解是遍历本线程的事件队列,将消息队列中的事件发送到对应对象进行处理,该事件队列的消息可以是用户发送的自定义是事件,也可以是定时器事件,也可以是对象删除删除,也可以是操作系统的发出的一些消息转换而来的事件(例如按钮的点击操作等)。
  • 事件队列中存在事件压缩的概念,压缩的概念是将事件队列中相同事件id(比如定时器事件),做相同事情的事件压缩为1个事件。

话不多说,直接上源码,清晰的将事件循环与线程的关系通过代码的方式展现出来

主线程的事件循环是由下面的代码触发

QCoreApplication::exec()

exec的内部实现如下:

int QCoreApplication::exec()
{
...QEventLoop eventLoop;int returnCode = eventLoop.exec();
...return returnCode;
}

通过上面的代码可以看到,定义了一个QEventLoop对象,对该对象调用了exec方法。QEventLoop的exec简要实现如下:

int QEventLoop::exec(ProcessEventsFlags flags)
{Q_D(QEventLoop);
...while (!d->exit)processEvents(flags | WaitForMoreEvents | EventLoopExec);
...return d->returnCode;
}

由上可以看出,QEventLoop下的exec调用了processEvents方法。该方法的实现如下:

bool QEventLoop::processEvents(ProcessEventsFlags flags)
{Q_D(QEventLoop);if (!d->threadData->eventDispatcher)return false;if (flags & DeferredDeletion)QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);return d->threadData->eventDispatcher->processEvents(flags);
}

由上可以看到在processEvent的实现中,首先判断了threadData中成员eventDispathcer是否存在,若不存在,则返回false,eventDispatcher从字面意思理解,是一个事件分发器,通过该对象指针调用其方法processEvents,到这里会有一个疑问,eventDispatcher是何时创建的呢?请看下面的代码:

QEventLoop::QEventLoop(QObject *parent): QObject(*new QEventLoopPrivate, parent)
{Q_D(QEventLoop);if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {qWarning(
"QEventLoop: Cannot be used without QApplication");} else {d->threadData.loadRelaxed()->ensureEventDispatcher();}
}
QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{Q_UNUSED(data);
#if defined(Q_OS_DARWIN)bool ok = false;int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);if (ok && value > 0)return new QEventDispatcherCoreFoundation;elsereturn new QEventDispatcherUNIX;
#elif !defined(QT_NO_GLIB)const bool isQtMainThread = data->thread.loadAcquire() == QCoreApplicationPrivate::mainThread();if (qEnvironmentVariableIsEmpty(
"QT_NO_GLIB")&& (isQtMainThread || qEnvironmentVariableIsEmpty(
"QT_NO_THREADED_GLIB"))&& QEventDispatcherGlib::versionSupported())return new QEventDispatcherGlib;elsereturn new QEventDispatcherUNIX;
#elsereturn new QEventDispatcherUNIX;
#endif
}

 

可以看到,eventDispatcher是在QEventLoop对象构造的过程中创建的,注意在这里生成的eventDispatcher已经是QEventDispatcherUnix类型了。下一步就是列出事件调度器的核心实现了,这里以linux为里介绍,所以QEventDispatcherUNIX下的实现processEvents实现,源码如下所示:

bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
{Q_D(QEventDispatcherUNIX);……QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);……timespec *tm = nullptr;……d->pollfds.append(d->threadPipe.prepare());int nevents = 0;switch (qt_safe_poll(d->pollfds.data(), d->pollfds.size(), tm)) {……}return (nevents > 0);
}void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,QThreadData *data)
{……while (i < data->postEventList.size()) {……const QPostEvent &pe = data->postEventList.at(i);++i;……QEvent *e = pe.event;QObject * r = pe.receiver;……QCoreApplication::sendEvent(r, e);}……
}

通过上面的代码可以看出,在事件调度器里面的processEvents实现中,首先调用sendPostedEvents方法将事件队列中的事件通过QCoreApplication::sendEvent调用发送给对应的对象,这里简要的提一下,sendevent方法是一个阻塞型的方法调用,仅用于本线程内的调用,他的内部内部核心实现是函数调用,即通过接收对象receiver的指针调用该对象的event方法,但是需要注意的是在调用event方法之前首先要调用该对象注册的事件监听器对象eventfilter方法。我会单独列出一个文章讲解sendevent,详细实现将在里面实现。

然后后调用了poll相关的方法,里面射击了threadPipe的相关用法,我通过查看资料了解到的是下面的实现会导致该循环让出cpu,等待事件队列中有属于再进行工作,这一块我需要再研究下后续补充。

总结

至此,我们了解了一个事件循环的本质及与事件循环与线程的关系:

  1. 事件循环与线程密不可分,虽然在一个线程中可以启动多个事件循环,但是这些事件循环共享同一个threadData,也就是说在一个线程内无论启动多少个事件循环,他们操作的是都是同一个事件调度器,并不会因为启动多个事件队列,而导致别的事件队列无法接收数据。
  2. 事件循环的本质就是将事件队列中的事件一一发送到本线程中的各个对象中进行处理
  3. 每个QObject对象都是线程相关的,每个QObject对象都存在一个threadData成员,这个成员包含了这个对象所属的线程信息


 

http://www.yidumall.com/news/24825.html

相关文章:

  • 用jsp做的网站需要什么工具秦皇岛网站seo
  • 洛阳市做网站的百度旗下的所有产品
  • 南城区做网站seo工具包
  • 做折页的网站seo的优化原理
  • 深圳企业网站制作制作网店代运营收费
  • 做通路富集分析的网站人教版优化设计电子书
  • 玉林网站建设seo排名优化是什么意思
  • 做游乐设施模型的网站国内搜索引擎排名2022
  • 邯郸做移动网站价格关键词智能调词工具
  • 外贸seo推广方法天津seo数据监控
  • 邯郸营销网站建设公司seo如何进行优化
  • 给公司做网站需要什么信息免费的个人网站html代码
  • 完成网站的建设工作网站制作过程
  • 航达建设集团有限公司网站百度运营优化师
  • 湛江手机建站模板seo推广优化外包公司
  • 题库网站怎样做新闻 近期大事件
  • 如何建立内部网站免费拓客软件
  • 网站建设 镇江丹阳东莞seo网站推广建设
  • 电子商务网站开发的基本流程网络营销策划方案框架
  • 哪个网站做民宿更好呢大侠seo外链自动群发工具
  • 暖暖 免费 视频 在线观看1西安百度提升优化
  • 网站优化公司怎么选推广方案设计
  • 青岛市网站建设公司推广方式有哪几种
  • 做网站开发的提成多少钱html制作网页代码
  • 做网站费是多少潍坊seo计费
  • 哪个行业最喜欢做网站手机网站建设平台
  • 网站建设新闻 常识网站排名seo教程
  • webform 做网站好不好关于市场营销的100个问题
  • 南宁百度网站设计推广引流最快的方法
  • 路由器设置用来做网站空间吗2023年11月新冠高峰