- 浏览: 57229 次
- 性别:
- 来自: 广州
最新评论
-
Joson_Coney:
11.
while( (*strDest++ = *strSr ...
c++笔试题汇总 -
Joson_Coney:
③ 1.
int func(x)
{
int countx = ...
c++笔试题汇总 -
Joson_Coney:
链表反向1:
#include <cstdlib&g ...
c++笔试题汇总
GTK+主循环(main loop)的工作原理 转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd 作者联系方式:Li XianJing <xianjimli at hotmail dot com> 更新时间:2007-3-17 我们知道GUI应用程序都是事件驱动的。这些事件大部分都来自于用户,比如键盘事件、鼠标事件或笔点事件。还有一些事件来自于系统内部,比如定时事件、socket事件和其它文件事件等等。在没有任何事件的情况下,应用程序处于睡眠状态。 因为这种事件驱动机制,GUI应用程序都毫无例外的需要一个主循环(main loop)。主循环(main loop)控制应用程序什么时候进入睡眠状态,什么时候被唤醒。主循环实现得好,应用程序才能工作正常又省电。 Win32 GUI应用程序的主循环是我们比较熟悉的,其大致如下: // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } 在这个主循环中,它不断的从消息队列中提取消息,然后分发给消息的目标(通常是窗口),直到GetMessage返回FALSE(收到WM_QUIT消息,一般调用PostQuitMessage)为止,如果队列中没有消息,应用程序就进入睡眠状态。这种方法简单明了,缺陷也是明显的,它只能挂在消息队列上,而不能同时挂在多个事件源上(如管道和socket等)。要挂在多个事件源上,需要使用其它方式,比如用WaitForMultipleObjects,那就比较麻烦了。 而在GTK+应用程序中,其主循环(main loop)更加简单,但是非常的不明了: gtk_main (); 不少人用GTK+写了很长时间的程序,还是觉得这行代码很神秘,不知道里面到底干了什么。本文试图分析一下gtk_main的工作原理: gtk_main主要是对glib的main loop的包装,基本上分为三步: 1. 调用初始化函数。 2. 进入glib main loop 3. 调用~初始化函数。 所以弄清楚glib main loop之后,gtk_main的实现也就尽收眼底了,本文重点分析glib的main loop的实现。main loop使用模式大致如下: loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); g_main_loop_new创建一个main loop对象,一个main loop对象只能被一个线程使用,但一个线程可以有多个main loop对象。在GTK+应用中,一个线程使用多个main loop的主要用途是实现模态对话框,它在gtk_dialog_run函数里创建一个新的main loop,通过该main loop分发消息,直到对话框关闭为止。 g_main_loop_run则是进入主循环,它会一直阻塞在这里,直到让它退出为止。有事件时,它就处理事件,没事件时就睡眠。 g_main_loop_quit则是用于退出主循环,相当于Win32下的PostQuitMessage函数。 Glib main loop的最大特点就是支持多事件源,使用非常方便。来自用户的键盘和鼠标事件、来自系统的定时事件和socket事件等等,还支持一个称为idle的事件源,其主要用途是实现异步事件。Main loop的基本组成如下图所示:
GMainLoop的主要部件是GMainContext,GMainContext可以在多个GMainLoop间共享,但要求这些GMainLoop都在同一个线程中运行,前面提到的模态对话框就属于这一类。GMainContext通常由多个GSource组成,GSource是事件源的抽象,任何事件源,只要实现GSource规定的接口,都可以挂到GMainContext中来。 GSource的接口函数有: 1. gboolean (*prepare) (GSource *source, gint *timeout_);进入睡眠之前,在g_main_context_prepare里,mainloop调用所有Source的prepare函数,计算最小的timeout时间,该时间决定下一次睡眠的时间。 2. gboolean (*check) (GSource *source); poll被唤醒后,在g_main_context_check里,mainloop调用所有Source的check函数,检查是否有Source已经准备好了。如果poll是由于错误或者超时等原因唤醒的,就不必进行dispatch了。 3. gboolean (*dispatch) (GSource*source, GSourceFunc callback,gpointer user_data); 当有Source准备好了,在g_main_context_dispatch里,mainloop调用所有Source的dispatch函数,去分发消息。 4. void (*finalize) (GSource *source); 在Source被移出时,mainloop调用该函数去销毁Source。 Main loop的工作流程简图如下:
下面我们看看几个内置Source的实现机制: Idle 它主要用实现异步事件,功能类似于Win32下的PostMessage。但它还支持重复执行的特性,根据用户注册的回调函数的返回值而定。 1. g_idle_prepare把超时设置为0,也就是即时唤醒,不进入睡眠状态。 2. g_idle_check 始终返回TRUE,表示准备好了。 3. g_idle_dispatch 调用用户注册的回调函数。 Timeout 它主要用于实现定时器,支持一次定时和重复定时,根据用户注册的回调函数的返回值而定。 1. g_timeout_prepare 计算下一次的超时时间。 2. g_timeout_check 检查超时时间是否到了,如果到了就返回TRUE,否则返回FALSE。 3. g_timeout_dispatch调用用户注册的回调函数。 线程可以向自己的mainloop中增加Source,也可以向其它线程的mainloop增加Source。向自己的mainloop中增加Source时,mainloop已经唤醒了,所以不会存在什么问题。而向其它线程的mainloop增加Source时,对方线程可能正挂在poll里睡眠,所以要想法唤醒它,否则Source可能来不及处理。在Linux下,这是通过wake_up_pipe管道实现的,mainloop在poll时,它除了等待所有的Source外,还会等待wake_up_pipe管道。要唤醒poll,调用g_main_context_wakeup_unlocked向wake_up_pipe里写入字母A就行了。 ~~end~~
发表评论
-
【转】Compiling with cython and mingw produces gcc: error: unrecognized command lin
2012-05-03 10:46 1063(From: http://stackoverflow.com ... -
【转】Lucene:基于Java的全文检索引擎简介
2012-04-19 16:15 677(转自:http://www.chedon ... -
Lucene:基于Java的全文检索引擎简介
2012-04-19 16:12 0<p>(转自:http://www.chedong ... -
spring源码阅读
2012-04-18 12:15 0框架包:struts2.3.1+spring 3.1.1+hi ... -
Java Annotation入门
2012-04-17 15:01 0(转自:http://www.blogjava.net/eri ... -
【转】SQL 2008 R2 problems on a Windows 2008 R2 Enterprise server
2012-03-30 15:15 1115(From: http://social.msdn.micro ... -
oracle管理
2012-03-06 10:21 0(转自:http://www.examw.co ... -
【转】 Struts2源代码分析(一)配置文件加载
2012-02-17 09:47 1125(转自:http://blog.csdn.net/zha ... -
【转】[WebZine]Struts2框架安全缺陷
2012-02-16 17:31 980(转自:http://huaidan.org/archives ... -
FreeBSD Install Nginx Webserver
2012-01-20 15:26 765(From: http://www.cyberciti.biz ... -
SSH系统,调用HibernateTemplate.find()方法的时候,会导致内存泄露?
2012-01-11 20:19 751(转自:http://www.iteye.co ... -
Java:对象的强、软、弱和虚引用
2012-01-09 15:00 555原创作品,允许转载,转载时请务必以超链接形式标明文 ... -
Spring构造器注入
2012-01-04 11:03 880(转自:http://javasight.net/2011/0 ... -
【转】Hibernate性能“暴差”引发的考证
2011-12-16 16:13 560(转http://blog.csdn.net/jxspace/ ... -
网络收藏夹 - 编程
2011-12-06 21:49 682网络收藏夹 1. 在线看jdk源码: http:// ... -
Hibernate、Spring和Struts工作原理及使用理由
2011-12-01 17:27 591(转自:http://tech.hexun.c ... -
Struts2源码分析--请求处理
2011-12-01 10:03 649(转自:http://www.blogjava.ne ... -
【转】spring 监听器 IntrospectorCleanupListener简介
2011-11-15 15:50 781spring中的提供了一个名为org.springfra ... -
java web学习笔记
2011-11-21 09:50 590Tomcat Configuration 资 ... -
c++笔试题汇总
2011-10-23 16:11 684(转自http://blog.csdn.net/dongfen ...
相关推荐
### GTK+ 主循环的工作原理详解 #### 一、引言 在GUI图形用户界面的应用程序设计中,事件驱动机制是一项核心的技术。...理解和掌握GTK+主循环的工作原理,对于深入学习GTK+乃至其他类似的GUI框架都有着重要的意义。
1. **事件循环(Event Loop)**: GTK+使用事件循环来处理来自用户的输入和其他事件。当组件需要更新其显示时,事件循环将触发相应的处理函数。 2. **曝光事件(Exposure Events)**: 当窗口的一部分需要重新绘制时,...
10. **事件循环**:理解GTK+的主事件循环(main loop)如何运行,以及如何使用`Gtk.main()`启动和退出。 在深入学习这些示例代码时,建议具备一定的Python基础和英语阅读能力。同时,配合GTK+3.0的官方文档和其他...
主循环(main loop)不断监听事件,包括属性改变事件。当事件发生时,GTK+会调用相应的处理函数,使得程序能够对事件做出反应。 7. **回调函数的编写**: 在连接到属性改变信号的回调函数中,你可以检查哪些属性...
1. GTK Main Loop:GTK应用程序基于事件驱动模型,其核心是主循环(Main Loop)。在这个循环中,GTK会处理各种事件,包括用户交互、定时器触发等。 2. g_timeout_add()函数:这是GTK中最常用的添加定时器的函数。它...
7. 主循环(Main Loop):GTK程序通过`gtk_main()`启动主循环,等待并处理来自窗口系统的事件。 在项目中的源代码文件`count1.c`和`count.c`很可能是实现计算器功能的C语言代码,其中包含了上述GTK组件的使用以及...
通过`g_main_loop_run()`启动这个循环,程序会等待并处理事件,直到调用`g_main_loop_quit()`退出循环。 6. **编译与链接**:编写GTK程序时,需要链接到GTK库。对于C语言,编译命令可能类似`gcc -o build_demo main...
- 对于C语言实现,开发者可能使用`glib`库进行内存管理和线程操作,用`GLib Main Loop`处理事件循环。 - 如果是Python,可以使用`PyGTK`或`GTK+3`的Python绑定,Python的内置数据结构和文件操作库会简化代码编写。...
通常,这可以通过`gtk_main()`或`g_main_loop_run()`实现。 6. **优化与性能**:考虑到性能,你应该谨慎使用定时器,特别是频繁触发的定时器,因为它们会占用事件循环,可能影响应用响应速度。 通过上述讲解,你...
事件循环是GLib中的重要概念,它允许程序在一个主循环中处理多个输入源和定时事件。`g_main_loop`和`g_main_context`是实现这一机制的关键组件,开发者可以注册回调函数来响应特定的事件。 文件系统操作部分,GLib...
当调用`g_main_loop_run`时,程序进入事件循环,不断调用`g_main_context_iteration`直到有退出事件发生。 在GLib中,事件可以分为两类:定时器事件和I/O事件。定时器事件通过`g_timeout_add`等函数设置,会在指定...
3. **Event Loop**: 为了响应用户的输入和窗口系统的事件,窗口管理器需要一个事件循环来处理这些事件。 4. **Window Decorations**: 窗口管理器需要为窗口添加标题栏、边框、最大化/最小化按钮等装饰元素,这通常...
4. **游戏循环**:游戏通常基于主循环(main game loop)进行,这个循环不断检测输入、更新游戏状态、渲染屏幕。学习如何构建和优化这样的循环至关重要。 5. **碰撞检测**:在"Flyppy Bird"中,检测小鸟与管道之间...
50.main processing loop 主处理循环 主处理循环是一个编程概念,定义了程序的主循环方式。它可以在编程语言中被使用,用于实现程序的主循环方式。 计算机专业术语50个翻译为我们提供了一个计算机专业领域的概述,...
- 通过`g_main_loop_run()`函数启动glib的事件循环,可以处理来自计时器或其他事件源的事件。 #### 三、提供上层建筑的基石-socket ##### 3.1 获取网络地址 - 在网络编程中,通过`g_socket_address_new_from_...
2. **主循环**:QEMU采用事件驱动的设计,支持异步API来处理各种事件,如文件描述符读写、定时器到期、延后工作等。全局互斥锁用于保护QEMU的核心代码,确保并发安全性。随着项目的演进,这些互斥锁正逐步被去除以...
43. Main Processing Loop(主处理循环):是程序运行的核心循环,用于处理输入、更新状态和渲染输出。 以上术语覆盖了计算机科学领域中的基础概念和组件,了解这些术语对于进行软件开发、系统维护和IT支持等工作至...
在嵌入式领域,有多种GUI框架可供选择,如QT、GTK、Clutter、Java (Android)、DirectFB、MiniGUI和MicroWindows/NanoX等。 QT,全称Quantum Toolkit,是一个流行的跨平台C++图形用户界面库,由Nokia公司开发并维护...