转载时请注明出处和作者联系方式
文章出处:http://blog.youkuaiyun.com/jack0106
作者联系方式:冯牮 fengjian0106@yahoo.com.cn
上一篇文章GMainLoop的实现原理和代码模型里面,介绍了GMainLoop的代码模型,其中的一些内容,还可以进一步讨论一下。
1. 之前提到过,GSource和被管理的文件的对应关系,不是 1对1,而是 1对n,这个n,甚至可以是0。这个的意思就是说,一个GSource,可以对应(管理)一个文件描述符,也可以同时对应(管理)多个文件描述符,也可以一个都不管理。
glib中已经提供了几个GSource的子类,其中的g_timeout_source_new(guint interval)和g_idle_source_new(void)这两个函数构造出的GSource子类,就并不使用文件描述符号。
GTimeoutSource,只需要保存设定的间隔时间,在poll轮循的prepare和check阶段,会去检查设定的这个间隔时间是否到达,如果到达设定的时间,则它的dispatch函数会被调用。
g_idle_source_new(void)其实都没有继承GSource,它也不需要和文件绑定,只不过它的优先级比较低,只有在poll轮询的空闲阶段,它的dispatch函数会被调用。而它的prepare和check函数,始终都是返回的TRUE。
2. GMainLoop怎样根据GSource的优先级进行调度?
在g_main_context_prepare()的时候,会从所有的GSource中找出最大的一个优先级,然后在g_main_context_query()的时候,只会把等于这个优先级的GSource对应的GPollFD添加到poll的监控集合中。基于这个优先级制度,GMainLoop就可以对GSource进行一个调度。以idle source为例,如果同时有一个GTimeoutSource和idle source,因为idle source的优先级更低,所有GMainLoop就不会把idle source添加到poll轮询的监控集合中,也就是说,直到GTimeoutSource从GMainLoop中移除,idle source的callback函数,才有机会被调用。