当前位置: 首页 > 面试题库 >

您将如何实现基本的事件循环?

庄子平
2023-03-14
问题内容

如果您使用的是gui工具包,那么您就会知道有一个事件循环/主循环,应在完成所有操作后执行该事件循环/主循环,这将使应用程序保持活动状态并响应不同的事件。例如,对于Qt,您可以在main()中执行此操作:

int main() {
    QApplication app(argc, argv);
    // init code
    return app.exec();
}

在这种情况下,app.exec()是应用程序的主循环。

实现这种循环的明显方法是:

void exec() {
    while (1) {
        process_events(); // create a thread for each new event (possibly?)
    }
}

但这会将CPU限制为100%,实际上是无用的。现在,我该如何实现这样一个事件响应循环,而又不会完全占用CPU?

答案在Python和/或C ++中受到赞赏。谢谢。

脚注:为了学习,我将实现自己的信号/插槽,并使用它们来生成自定义事件(例如go_forward_event(steps))。但是,如果您知道如何手动使用系统事件,那么我也想知道。


问题答案:

我曾经想知道很多相同的东西!

GUI主循环如下所示,为伪代码:

void App::exec() {
    for(;;) {
        vector<Waitable> waitables;
        waitables.push_back(m_networkSocket);
        waitables.push_back(m_xConnection);
        waitables.push_back(m_globalTimer);
        Waitable* whatHappened = System::waitOnAll(waitables);
        switch(whatHappened) {
            case &m_networkSocket: readAndDispatchNetworkEvent(); break;
            case &m_xConnection: readAndDispatchGuiEvent(); break;
            case &m_globalTimer: readAndDispatchTimerEvent(); break;
        }
    }
}

什么是“等待”?好吧,这取决于系统。在UNIX上,它称为“文件描述符”,而“ waitOnAll”是::
select系统调用。在UNIX上,所谓的vector<Waitable>是a ::fd_set,实际上是通过“
whatHappened”查询的FD_ISSET。实际的等待句柄以各种方式获取,例如m_xConnection可以从::
XConnectionNumber()获取。X11还提供了一个高层次的,可移植的API为这一点- :: XNextEvent例行()
-但如果你使用,你将无法等待几个事件源 同时


封锁如何运作?“
waitOnAll”是一个系统调用,告诉操作系统将您的进程置于“睡眠列表”中。这意味着在其中一个等待对象上发生事件之前,不会给您任何CPU时间。那么,这意味着您的进程处于空闲状态,消耗了0%的CPU。当事件发生时,您的进程将对此做出短暂反应,然后返回空闲状态。GUI应用程序几乎将
所有 时间 花在空闲上。

睡眠时所有CPU周期会怎样?依靠。有时,另一个过程将对其有用。否则,您的操作系统将忙于循环CPU,或将其置于临时低功耗模式等。

请询问更多细节!



 类似资料:
  • 问题内容: 我试图在PyQt中发出自定义事件。一个小部件将发出,另一个小部件将监听事件,但是两个小部件不需要关联。 在JavaScript中,我会这样做 编辑:我知道信号和插槽,但只知道如何在父级和子级之间使用它们。我如何在任意不相关的小部件之间使用这种机制(或其他机制)? 问题答案: 在PyQt中,以下说明: 等价的 以类似的方式: 等价的 但是最大的区别是“文档”对象的范围,因为连接是在全局元

  • 本文向大家介绍基于spring如何实现事件驱动实例代码,包括了基于spring如何实现事件驱动实例代码的使用技巧和注意事项,需要的朋友参考一下 干货点 通过阅读该篇博客,你可以了解了解java的反射机制、可以了解如何基于spring生命周期使用自定义注解解决日常研发问题。具体源码可以点击链接。 问题描述 在日常研发中,经常会遇见业务A的某个action被触发后,同时触发业务B的action的行为,

  • 本文向大家介绍Python基于Tkinter实现的记事本实例,包括了Python基于Tkinter实现的记事本实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python基于Tkinter实现的记事本。分享给大家供大家参考。具体如下: 希望本文所述对大家的Python程序设计有所帮助。

  • 本文向大家介绍浏览器事件循环与vue nextTicket的实现,包括了浏览器事件循环与vue nextTicket的实现的使用技巧和注意事项,需要的朋友参考一下 同步:就是在执行栈中(主线程)执行的代码 异步:就是在异步队列(macroTask、microTask)中的代码 简单理解区别就是:异步是需要延迟执行的代码 线程和进程 进程:进程是应用程序的执行实例,每一个进程都是由私有的虚拟地址空间

  • 本文向大家介绍基于Java实现记事本功能,包括了基于Java实现记事本功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Java实现记事本的具体代码,供大家参考,具体内容如下 编写一个具有菜单以及编辑、查找、替换、复制、粘贴功能,且具有新建、打开和保存文件功能的记事本(MyNotepad)。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。