<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Computer, Electron and Technology &#187; 循环</title>
	<atom:link href="http://www.donevii.com/post/tag/%e5%be%aa%e7%8e%af/feed" rel="self" type="application/rss+xml" />
	<link>http://www.donevii.com</link>
	<description>关注技术、移动互联网以及一切 GEEK &#38; NERD 的事情</description>
	<lastBuildDate>Wed, 21 Dec 2011 10:49:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>GTK+主循环(main loop)的工作原理</title>
		<link>http://www.donevii.com/post/580.html</link>
		<comments>http://www.donevii.com/post/580.html#comments</comments>
		<pubDate>Mon, 20 Oct 2008 14:09:49 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[c/c++/c#]]></category>
		<category><![CDATA[doc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[glib]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[循环]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=580</guid>
		<description><![CDATA[转至：http://www.builder.com.cn 我们知道GUI应用程序都是事件驱动的。这些事件大部分都来自于用户，比如键盘事件、鼠标事件或笔点事件。还有一些事件来自于系统内部，比如定时事件、socket事件... ]]></description>
			<content:encoded><![CDATA[<p>转至：http://www.builder.com.cn</p>
<p><span style="font-family: 宋体;"><span style="font-size: small;">我们知道<span lang="EN-US">GUI应用程序都是事件驱动的。这些事件大部分都来自于用户，比如键盘事件、鼠标事件或笔点事件。还有一些事件来自于系统内部，比如定时事件、socket事件和其它文件事件等等。在没有任何事件的情况下，应用程序处于睡眠状态。</span></span></span></p>
<p><span style="font-family: 宋体;" lang="EN-US"><span style="font-size: small;"> </span></span></p>
<p><span style="font-family: 宋体;"><span style="font-size: small;">因为这种事件驱动机制，<span lang="EN-US">GUI应用程序都毫无例外的需要一个主循环(main loop)。主循环(main loop)控制应用程序什么时候进入睡眠状态，什么时候被唤醒。主循环实现得好，应用程序才能工作正常又省电。</span></span></span></p>
<p><span style="font-family: 宋体;" lang="EN-US"><span style="font-size: small;"> </span></span></p>
<p><span style="font-family: 宋体;" lang="EN-US"><span style="font-size: small;">Win32 GUI应用程序的主循环是我们比较熟悉的，其大致如下：</span></span></p>
<table style="border: medium none; background: #e6e6e6 none repeat scroll 0% 0%; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" bgcolor="#e6e6e6">
<tbody>
<tr>
<td style="border: 0.5pt solid windowtext; padding: 0cm 5.4pt; width: 426.1pt; background-color: transparent;" width="568" valign="top">
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span></span><span style="color: #009900;" lang="EN-US">// Main message loop:</span></span></span></p>
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span></span><span style="color: blue;" lang="EN-US">while</span><span style="color: black;" lang="EN-US"> (</span><span style="color: #a000a0;" lang="EN-US">GetMessage</span><span style="color: black;" lang="EN-US">(&amp;</span><span style="color: gray;" lang="EN-US">msg</span><span style="color: black;" lang="EN-US">, </span><span style="color: #a000a0;" lang="EN-US">NULL</span><span style="color: black;" lang="EN-US">, 0, 0)) </span></span></span></p>
<p align="left"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span> </span>{</span></span></span></p>
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span></span><span style="color: blue;" lang="EN-US">if</span><span style="color: black;" lang="EN-US"> (!</span><span style="color: #a000a0;" lang="EN-US">TranslateAccelerator</span><span style="color: black;" lang="EN-US">(</span><span style="color: gray;" lang="EN-US">msg</span><span style="color: black;" lang="EN-US">.</span><span style="color: gray;" lang="EN-US">hwnd</span><span style="color: black;" lang="EN-US">, </span><span style="color: gray;" lang="EN-US">hAccelTable</span><span style="color: black;" lang="EN-US">, &amp;</span><span style="color: gray;" lang="EN-US">msg</span><span style="color: black;" lang="EN-US">)) </span></span></span></p>
<p align="left"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span> </span>{</span></span></span></p>
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span></span><span style="color: #880000;" lang="EN-US">TranslateMessage</span><span style="color: black;" lang="EN-US">(&amp;</span><span style="color: gray;" lang="EN-US">msg</span><span style="color: black;" lang="EN-US">);</span></span></span></p>
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span></span><span style="color: #a000a0;" lang="EN-US">DispatchMessage</span><span style="color: black;" lang="EN-US">(&amp;</span><span style="color: gray;" lang="EN-US">msg</span><span style="color: black;" lang="EN-US">);</span></span></span></p>
<p align="left"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span> </span>}</span></span></span></p>
<p><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span> </span>}</span></span></span></td>
</tr>
</tbody>
</table>
<p><span style="font-family: 宋体;" lang="EN-US"><span style="font-size: small;"> </span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">在这个主循环中，它不断的从消息队列中提取消息，然后分发给消息的目标</span><span lang="EN-US"><span style="font-family: Times New Roman;">(</span></span><span style="font-family: 宋体;">通常是窗口</span><span lang="EN-US"><span style="font-family: Times New Roman;">)</span></span><span style="font-family: 宋体;">，直到</span><span lang="EN-US"><span style="font-family: Times New Roman;">GetMessage</span></span><span style="font-family: 宋体;">返回</span><span lang="EN-US"><span style="font-family: Times New Roman;">FALSE</span></span><span style="font-family: 宋体;">（收到</span><span lang="EN-US"><span style="font-family: Times New Roman;">WM_QUIT</span></span><span style="font-family: 宋体;">消息，一般调用</span><span lang="EN-US"><span style="font-family: Times New Roman;">PostQuitMessage</span></span><span style="font-family: 宋体;">）为止，如果队列中没有消息，应用程序就进入睡眠状态。这种方法简单明了，缺陷也是明显的，它只能挂在消息队列上，而不能同时挂在多个</span><span style="color: black; font-family: 宋体;">事件</span><span style="font-family: 宋体;">源上</span><span lang="EN-US"><span style="font-family: Times New Roman;">(</span></span><span style="font-family: 宋体;">如管道和</span><span lang="EN-US"><span style="font-family: Times New Roman;">socket</span></span><span style="font-family: 宋体;">等</span><span lang="EN-US"><span style="font-family: Times New Roman;">)</span></span><span style="font-family: 宋体;">。要挂在多个</span><span style="color: black; font-family: 宋体;">事件</span><span style="font-family: 宋体;">源上，需要使用其它方式，比如用</span><span lang="EN-US"><span style="font-family: Times New Roman;">WaitForMultipleObjects</span></span><span style="font-family: 宋体;">，那就比较麻烦了。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">而在</span><span lang="EN-US"><span style="font-family: Times New Roman;"><a href="http://www.donevii.com/post/tag/gtk" class="st_tag internal_tag" rel="tag" title="Posts tagged with gtk">GTK</a>+</span></span><span style="font-family: 宋体;">应用程序中，其</span><span style="font-family: 宋体;">主循环<span lang="EN-US">(main loop)更加简单，但是非常的不明了：</span></span></span></p>
<table style="border: medium none; background: #e6e6e6 none repeat scroll 0% 0%; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" bgcolor="#e6e6e6">
<tbody>
<tr>
<td style="border: 0.5pt solid windowtext; padding: 0cm 5.4pt; width: 426.1pt; background-color: transparent;" width="568" valign="top"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">gtk_main ();</span></span></td>
</tr>
</tbody>
</table>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">不少人用</span><span lang="EN-US"><span style="font-family: Times New Roman;">GTK+</span></span><span style="font-family: 宋体;">写了很长时间的程序，还是觉得这行代码很神秘，不知道里面到底干了什么。本文试图分析一下</span><span lang="EN-US"><span style="font-family: Times New Roman;">gtk_main</span></span><span style="font-family: 宋体;">的工作原理：</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">gtk_main</span></span><span style="font-family: 宋体;">主要是对</span><span lang="EN-US"><span style="font-family: Times New Roman;"><a href="http://www.donevii.com/post/tag/glib" class="st_tag internal_tag" rel="tag" title="Posts tagged with glib">glib</a></span></span><span style="font-family: 宋体;">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="font-family: 宋体;">的包装，基本上分为三步：</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;">1.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><span style="font-family: 宋体;"><span style="font-size: small;">调用初始化函数。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;">2.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">进入</span><span lang="EN-US"><span style="font-family: Times New Roman;">glib main loop</span></span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;">3.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">调用</span><span lang="EN-US"><span style="font-family: Times New Roman;">~</span></span><span style="font-family: 宋体;">初始化函数。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">所以弄清楚</span><span lang="EN-US"><span style="font-family: Times New Roman;">glib main loop</span></span><span style="font-family: 宋体;">之后，</span><span lang="EN-US"><span style="font-family: Times New Roman;">gtk_main</span></span><span style="font-family: 宋体;">的实现也就尽收眼底了，本文重点分析</span><span lang="EN-US"><span style="font-family: Times New Roman;">glib</span></span><span style="font-family: 宋体;">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="font-family: 宋体;">的实现。</span><span lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="font-family: 宋体;">使用模式大致如下：</span></span></p>
<table style="border: medium none; background: #e6e6e6 none repeat scroll 0% 0%; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" bgcolor="#e6e6e6">
<tbody>
<tr>
<td style="border: 0.5pt solid windowtext; padding: 0cm 5.4pt; width: 426.1pt; background-color: transparent;" width="568" valign="top">
<p align="left"><span style="font-family: Times New Roman;"><span style="font-size: small;"><span style="color: black;" lang="EN-US">loop = g_main_loop_new (</span><span style="color: #a000a0;" lang="EN-US">NULL</span><span style="color: black;" lang="EN-US">, </span><span style="color: #a000a0;" lang="EN-US">TRUE</span><span style="color: black;" lang="EN-US">);</span></span></span></p>
<p align="left"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">g_main_loop_run (loop);</span></span></p>
</td>
</tr>
</tbody>
</table>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">g_main_loop_new</span></span><span style="color: black; font-family: 宋体;">创建一个</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">对象，一个</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">对象只能被一个线程使用，但一个线程可以有多个</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">对象。在</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">GTK+</span></span><span style="color: black; font-family: 宋体;">应用中，一个线程使用多个</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">的主要用途是实现模态对话框，它在</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">gtk_dialog_run</span></span><span style="color: black; font-family: 宋体;">函数里创建一个新的</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">，通过该</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">main loop</span></span><span style="color: black; font-family: 宋体;">分发消息，直到对话框关闭为止。</span></span></p>
<p><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">g_main_loop_run</span></span><span style="color: black; font-family: 宋体;">则是进入主循环，它会一直阻塞在这里，直到让它退出为止。有事件时，它就处理事件，没事件时就睡眠。</span></span></p>
<p><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">g_main_loop_quit</span></span><span style="font-family: 宋体;">则是用于退出</span><span style="color: black; font-family: 宋体;">主循环，相当于</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">Win32</span></span><span style="color: black; font-family: 宋体;">下的</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">PostQuitMessage</span></span><span style="font-family: 宋体;">函数。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">Glib main loop</span></span><span style="color: black; font-family: 宋体;">的最大特点就是支持多事件源，使用非常方便。来自用户的键盘和鼠标事件、来自系统的定时事件和</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">socket</span></span><span style="color: black; font-family: 宋体;">事件等等，还支持一个称为</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">idle</span></span><span style="color: black; font-family: 宋体;">的事件源，其主要用途是实现异步事件。</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">Main loop</span></span><span style="color: black; font-family: 宋体;">的基本组成如下图所示：</span></span></p>
<p><span style="font-size: small;"><span lang="EN-US"></span></span></p>
<p><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/absurd/211144/o_mainloop_struct.jpg" alt="" /></span></span></span></p>
<p><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">GMainLoop</span></span><span style="font-family: 宋体;">的主要部件是</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainContext</span></span><span style="font-family: 宋体;">，</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainContext</span></span><span style="font-family: 宋体;">可以在多个</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainLoop</span></span><span style="font-family: 宋体;">间共享，但要求这些</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainLoop</span></span><span style="font-family: 宋体;">都在同一个线程中运行，前面提到的模态对话框就属于这一类。</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainContext</span></span><span style="font-family: 宋体;">通常由多个</span><span lang="EN-US"><span style="font-family: Times New Roman;">GSource</span></span><span style="font-family: 宋体;">组成，</span><span lang="EN-US"><span style="font-family: Times New Roman;">GSource</span></span><span style="font-family: 宋体;">是事件源的抽象，任何事件源，只要实现</span><span lang="EN-US"><span style="font-family: Times New Roman;">GSource</span></span><span style="font-family: 宋体;">规定的接口，都可以挂到</span><span lang="EN-US"><span style="font-family: Times New Roman;">GMainContext</span></span><span style="font-family: 宋体;">中来。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">GSource</span></span><span style="font-family: 宋体;">的接口函数有：</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">1.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">gboolean (*prepare)<span> </span>(GSource<span> </span>*source, gint<span> </span>*timeout_);</span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">进入睡眠之前，在</span><span lang="EN-US"><span style="font-family: Times New Roman;">g_main_context_prepare</span></span><span style="font-family: 宋体;">里，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">调用所有</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">prepare</span></span><span style="font-family: 宋体;">函数，计算最小的</span><span lang="EN-US"><span style="font-family: Times New Roman;">timeout</span></span><span style="font-family: 宋体;">时间，该时间决定下一次睡眠的时间。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">2.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">gboolean (*check)<span> </span>(GSource<span> </span>*source); poll</span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">被唤醒后，在</span><span lang="EN-US"><span style="font-family: Times New Roman;">g_main_context_check</span></span><span style="font-family: 宋体;">里，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">调用所有</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">check</span></span><span style="font-family: 宋体;">函数，检查是否有</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">已经准备好了。如果</span><span lang="EN-US"><span style="font-family: Times New Roman;">poll</span></span><span style="font-family: 宋体;">是由于错误或者超时等原因唤醒的，就不必进行</span><span lang="EN-US"><span style="font-family: Times New Roman;">dispatch</span></span><span style="font-family: 宋体;">了。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">3.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">gboolean (*dispatch) (GSource*source, GSourceFunc callback,gpointer user_data); </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">当有</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">准备好了，在</span><span lang="EN-US"><span style="font-family: Times New Roman;">g_main_context_dispatch</span></span><span style="font-family: 宋体;">里，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">调用所有</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">dispatch</span></span><span style="font-family: 宋体;">函数，去分发消息。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">4.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">void<span> </span>(*finalize) (GSource<span> </span>*source); </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">在</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">被移出时，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">调用该函数去销毁</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">Main loop</span></span><span style="font-family: 宋体;">的工作流程简图如下：</span></span></p>
<p><span lang="EN-US"></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/absurd/211144/o_mainloop_workflow.jpg" alt="" /></span></span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">下面我们看看几个内置</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">的实现机制：</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Times New Roman;"><strong><span lang="EN-US">Idle</span></strong><span lang="EN-US"> </span></span><span style="font-family: 宋体;">它主要用实现异步事件，功能类似于</span><span lang="EN-US"><span style="font-family: Times New Roman;">Win32</span></span><span style="font-family: 宋体;">下的</span><span lang="EN-US"><span style="font-family: Times New Roman;">PostMessage</span></span><span style="font-family: 宋体;">。但它还支持重复执行的特性，根据用户注册的回调函数的返回值而定。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">1.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_idle_prepare</span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">把超时设置为</span><span lang="EN-US"><span style="font-family: Times New Roman;">0</span></span><span style="font-family: 宋体;">，也就是即时唤醒，不进入睡眠状态。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">2.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_idle_check </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">始终返回</span><span lang="EN-US"><span style="font-family: Times New Roman;">TRUE</span></span><span style="font-family: 宋体;">，表示准备好了。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">3.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_idle_dispatch </span></span></span><span style="font-family: 宋体;"><span style="font-size: small;">调用用户注册的回调函数。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Times New Roman;"><strong><span lang="EN-US">Timeout</span></strong><span lang="EN-US"> </span></span><span style="font-family: 宋体;">它主要用于实现定时器，支持一次定时和重复定时，根据用户注册的回调函数的返回值而定。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">1.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_timeout_prepare </span></span></span><span style="font-family: 宋体;"><span style="font-size: small;">计算下一次的超时时间。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">2.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_timeout_check </span></span></span><span style="font-size: small;"><span style="font-family: 宋体;">检查超时时间是否到了，如果到了就返回</span><span lang="EN-US"><span style="font-family: Times New Roman;">TRUE</span></span><span style="font-family: 宋体;">，否则返回</span><span lang="EN-US"><span style="font-family: Times New Roman;">FALSE</span></span><span style="font-family: 宋体;">。</span></span></p>
<p><span style="font-family: Times New Roman;"><span lang="EN-US"><span style="font-size: small;">3.</span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span><span lang="EN-US"><span style="font-size: small;">g_timeout_dispatch</span></span></span><span style="font-family: 宋体;"><span style="font-size: small;">调用用户注册的回调函数。</span></span></p>
<p><span lang="EN-US"><span style="font-family: Times New Roman;"><span style="font-size: small;"> </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">线程可以向自己的</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">中增加</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">，也可以向其它线程的</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">增加</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">。向自己的</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">中增加</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">时，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">已经唤醒了，所以不会存在什么问题。而向其它线程的</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">增加</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">时，对方线程可能正挂在</span><span lang="EN-US"><span style="font-family: Times New Roman;">poll</span></span><span style="font-family: 宋体;">里睡眠，所以要想法唤醒它，否则</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">可能来不及处理。在</span><span lang="EN-US"><span style="font-family: Times New Roman;"><a href="http://www.donevii.com/post/tag/linux" class="st_tag internal_tag" rel="tag" title="Posts tagged with linux">Linux</a></span></span><span style="font-family: 宋体;">下，这是通过</span><span lang="EN-US"><span style="font-family: Times New Roman;">wake_up_pipe</span></span><span style="font-family: 宋体;">管道实现的，</span><span lang="EN-US"><span style="font-family: Times New Roman;">mainloop</span></span><span style="font-family: 宋体;">在</span><span lang="EN-US"><span style="font-family: Times New Roman;">poll</span></span><span style="font-family: 宋体;">时，它除了等待所有的</span><span lang="EN-US"><span style="font-family: Times New Roman;">Source</span></span><span style="font-family: 宋体;">外，还会等待</span><span lang="EN-US"><span style="font-family: Times New Roman;">wake_up_pipe</span></span><span style="font-family: 宋体;">管道。要唤醒</span><span lang="EN-US"><span style="font-family: Times New Roman;">poll</span></span><span style="font-family: 宋体;">，调用</span><span lang="EN-US"><span style="font-family: Times New Roman;">g_main_context_wakeup_unlocked</span></span><span style="font-family: 宋体;">向</span><span lang="EN-US"><span style="font-family: Times New Roman;">wake_up_pipe</span></span><span style="font-family: 宋体;">里写入字母</span><span lang="EN-US"><span style="font-family: Times New Roman;">A</span></span><span style="font-family: 宋体;">就行了。</span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/580.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>9个部位粉刺痘痘不同歼灭法</title>
		<link>http://www.donevii.com/post/369.html</link>
		<comments>http://www.donevii.com/post/369.html#comments</comments>
		<pubDate>Mon, 17 Dec 2007 07:29:20 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[下巴]]></category>
		<category><![CDATA[习惯]]></category>
		<category><![CDATA[体质]]></category>
		<category><![CDATA[便秘]]></category>
		<category><![CDATA[医学]]></category>
		<category><![CDATA[印堂]]></category>
		<category><![CDATA[卵巢]]></category>
		<category><![CDATA[压力]]></category>
		<category><![CDATA[呼吸]]></category>
		<category><![CDATA[堆积]]></category>
		<category><![CDATA[异常]]></category>
		<category><![CDATA[循环]]></category>
		<category><![CDATA[心情]]></category>
		<category><![CDATA[感冒]]></category>
		<category><![CDATA[机能]]></category>
		<category><![CDATA[歼灭]]></category>
		<category><![CDATA[毒素]]></category>
		<category><![CDATA[消化]]></category>
		<category><![CDATA[生殖]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[皮肤]]></category>
		<category><![CDATA[皮脂]]></category>
		<category><![CDATA[睡眠]]></category>
		<category><![CDATA[禁欲]]></category>
		<category><![CDATA[粉刺]]></category>
		<category><![CDATA[系统]]></category>
		<category><![CDATA[纵欲]]></category>
		<category><![CDATA[脸颊]]></category>
		<category><![CDATA[脾气]]></category>
		<category><![CDATA[血液]]></category>
		<category><![CDATA[额头]]></category>
		<category><![CDATA[鼻尖]]></category>
		<category><![CDATA[鼻梁]]></category>
		<category><![CDATA[鼻翼]]></category>

		<guid isPermaLink="false">http://www.donevii.com/post/369.html</guid>
		<description><![CDATA[     根据中医学的观点,粉刺是由于体内积存的热而引起的皮肤炎症。所以说,粉刺其实与体质也有关联。而根据脸上粉刺分布部位的不同,对付粉刺对策也不尽相同。不妨来对照下表,看看自己... ]]></description>
			<content:encoded><![CDATA[<p>     根据中医学的观点,粉刺是由于体内积存的热而引起的皮肤炎症。所以说,粉刺其实与体质也有关联。而根据脸上粉刺分布部位的不同,对付粉刺对策也不尽相同。不妨来对照下表,看看自己该注意些什么吧!<br />
<strong>额头：</strong><br />
表示心火旺,血液循环欠佳。可能压力较大,脾气较不好。<br />
对策：<br />
应养成良好的生活习惯,保证充足的睡眠,放松心情。记得多多喝水。<br />
<strong>左脸颊：</strong><br />
可能是肝<a href="http://www.weyii.com/group/go/basiccare" class="broken_link">功能</a>不太好,肝脏的分泌、排毒或是造血功能出了问题。容易感到疲劳和口渴。<br />
对策：<br />
保持作息正常,心情舒畅。饮食注重清热,泻肝火。<br />
<strong>右脸颊：</strong><br />
可能是肺部功能失常,或是体质容易过敏。也可能是感冒前兆。<br />
对策：<br />
平时应注意呼吸道的保养,泻肺热。尽量避免海鲜等易过敏的食物。<br />
<strong><a href="http://www.donevii.com/post/tag/%e5%8d%b0%e5%a0%82" class="st_tag internal_tag" rel="tag" title="Posts tagged with 印堂">印堂</a>：</strong><br />
痘痘出现在两眉之间,通常容易出现胸闷、心悸或心律不齐现象。<br />
对策：<br />
不要进行过于<a href="http://www.weyii.com/group/go/basiccare" class="broken_link">激烈</a>的运动。<br />
<strong>两眼及鼻梁之间：</strong><br />
也可能是肝功能不好。<br />
对策：<br />
生活作息要正常,避免熬夜、喝酒、抽烟。<br />
<strong><a href="http://www.donevii.com/post/tag/%e9%bc%bb%e5%b0%96" class="st_tag internal_tag" rel="tag" title="Posts tagged with 鼻尖">鼻尖</a>：</strong><br />
可能是胃火大,消化系统异常。<br />
对策：<br />
少吃寒性食物。因为寒性食物容易引起胃酸分泌,造成胃火过大。<br />
<strong><a href="http://www.donevii.com/post/tag/%e9%bc%bb%e7%bf%bc" class="st_tag internal_tag" rel="tag" title="Posts tagged with 鼻翼">鼻翼</a>：</strong><br />
一般由于皮脂分泌较多。也可能跟卵巢机能或生殖系统有关。<br />
对策：<br />
定要及时清除毛孔污垢。另外,不要过度纵欲或禁欲。多多享受<a href="http://www.weyii.com/group/go/basiccare" class="broken_link">健康</a>自然的环境。<br />
<strong>唇周：</strong><br />
可能是便秘导致体内毒素堆积。<br />
对策：<br />
多吃富含纤维的蔬菜水果,调理饮食习惯。<br />
<strong><a href="http://www.donevii.com/post/tag/%e4%b8%8b%e5%b7%b4" class="st_tag internal_tag" rel="tag" title="Posts tagged with 下巴">下巴</a>：</strong><br />
通常由内分泌失调引起。月经来的前几天<a href="http://www.weyii.com/group/go/basiccare" class="broken_link">痘痘</a>常会发在这个部位。<br />
对策：<br />
少吃冰冷的东西,尽量多吃清淡的食品。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/369.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

