<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>朱文昊 Albert Zhu &#187; 技术</title>
	<atom:link href="http://zhuwenhao.com/category/%e6%8a%80%e6%9c%af/feed/" rel="self" type="application/rss+xml" />
	<link>http://zhuwenhao.com</link>
	<description>朱文昊的中文博客－－专注技术，向往自由</description>
	<lastBuildDate>Wed, 25 Aug 2010 00:53:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>自己动手制作U3P安装软件</title>
		<link>http://zhuwenhao.com/545/%e6%8a%80%e6%9c%af/%e8%87%aa%e7%94%b1%e8%bd%af%e4%bb%b6%e7%a4%be%e5%8c%ba/%e8%87%aa%e5%b7%b1%e5%8a%a8%e6%89%8b%e5%88%b6%e4%bd%9cu3p%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/</link>
		<comments>http://zhuwenhao.com/545/%e6%8a%80%e6%9c%af/%e8%87%aa%e7%94%b1%e8%bd%af%e4%bb%b6%e7%a4%be%e5%8c%ba/%e8%87%aa%e5%b7%b1%e5%8a%a8%e6%89%8b%e5%88%b6%e4%bd%9cu3p%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 08:37:57 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[自由软件社区]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=545</guid>
		<description><![CDATA[使用PackageFactory for U3可以自己制作U3软件安装到自己的U3优盘上.
软件下载地址: http://www.eure.ca/
因为很多软件在设计的时候都会保存信息到Documents目录或者使用注册表项,所以从零开始制作优盘移动软件很难,幸好有Portable  Apps项目,该项目已经把很多热门软件移动化,我利用这些程序制作自己的U3软件,就非常简单了.  首先下载需要的软件,安装,(路径可以选择安装在硬盘上,安装速度快)
本文末尾提供了我制作的二十几个u3p文件,您可以直接下载.
使用方法:
1,启动界面

2,点击右下角Advanced Mode (Wizard Mode我不会用,会出错)进入下图界面


3,点击Host Folder,然后Add File: 找到Portable Apps安装目录下面的主exe文件,例如Songbird  Portable.exe

4,程序自己解析该exe,提取名称,图标,版本信息等

5,再返回Host Folder

6,增加Portable Apps 目录下所有相关的子目录

7,回到Summary界面,点击Create a U3P file, 界面如下,过一会儿一个你自己制作的U3安装软件.u3p就出来了.

这个.u3p就可以安装在U3launchpad里面了.
下面提供我制作的文件,省得大家重复劳动.

]]></description>
			<content:encoded><![CDATA[<p>使用PackageFactory for U3可以自己制作U3软件安装到自己的U3优盘上.</p>
<p>软件下载地址: <a href="http://www.eure.ca/">http://www.eure.ca/</a></p>
<p>因为很多软件在设计的时候都会保存信息到Documents目录或者使用注册表项,所以从零开始制作优盘移动软件很难,幸好有<a href="http://portableapps.com/apps" target="_blank">Portable  Apps</a>项目,该项目已经把很多热门软件移动化,我利用这些程序制作自己的U3软件,就非常简单了.  首先下载需要的软件,安装,(路径可以选择安装在硬盘上,安装速度快)</p>
<p>本文末尾提供了我制作的二十几个u3p文件,您可以直接下载.</p>
<p>使用方法:</p>
<p>1,启动界面</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_4.png"><img class="alignnone size-medium wp-image-527" title="WindowsLiveWriterU3APP_AE5Bimage_4.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_4-300x222.png" alt="" width="300" height="222" /></a></p>
<p>2,点击右下角Advanced Mode (Wizard Mode我不会用,会出错)进入下图界面</p>
<p><span id="more-545"></span></p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_8.png"><img class="alignnone size-medium wp-image-529" title="WindowsLiveWriterU3APP_AE5Bimage_8.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_8-300x222.png" alt="" width="300" height="222" /></a></p>
<p>3,点击Host Folder,然后Add File: 找到Portable Apps安装目录下面的主exe文件,例如Songbird  Portable.exe</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_10.png"><img class="alignnone size-medium wp-image-531" title="WindowsLiveWriterU3APP_AE5Bimage_10.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_10-300x222.png" alt="" width="300" height="222" /></a></p>
<p>4,程序自己解析该exe,提取名称,图标,版本信息等</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_12.png"><img class="alignnone size-medium wp-image-533" title="WindowsLiveWriterU3APP_AE5Bimage_12.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_12-300x222.png" alt="" width="300" height="222" /></a></p>
<p>5,再返回Host Folder</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_14.png"><img class="alignnone size-medium wp-image-535" title="WindowsLiveWriterU3APP_AE5Bimage_14.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_14-300x222.png" alt="" width="300" height="222" /></a></p>
<p>6,增加Portable Apps 目录下所有相关的子目录</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_16.png"><img class="alignnone size-medium wp-image-537" title="WindowsLiveWriterU3APP_AE5Bimage_16.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_16-300x222.png" alt="" width="300" height="222" /></a></p>
<p>7,回到Summary界面,点击Create a U3P file, 界面如下,过一会儿一个你自己制作的U3安装软件.u3p就出来了.</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_18.png"><img class="alignnone size-medium wp-image-539" title="WindowsLiveWriterU3APP_AE5Bimage_18.png" src="http://zhuwenhao.com/wp-content/uploads/2010/06/WindowsLiveWriterU3APP_AE5Bimage_18-300x222.png" alt="" width="300" height="222" /></a></p>
<p>这个.u3p就可以安装在U3launchpad里面了.</p>
<p>下面提供我制作的文件,省得大家重复劳动.<br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=7-ZipPortable" title=" downloaded 20 times" >7-ZipPortable (20)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=AudacityPortable" title=" downloaded 14 times" >AudacityPortable (14)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=BonkEncPortable" title=" downloaded 13 times" >BonkEncPortable (13)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=ClamWinPortable" title=" downloaded 13 times" >ClamWinPortable (13)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=ConvertAllPortable" title=" downloaded 12 times" >ConvertAllPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=EraserDropPortable" title=" downloaded 16 times" >EraserDropPortable (16)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=EraserPortable" title=" downloaded 11 times" >EraserPortable (11)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=FoxitReaderPortable" title=" downloaded 17 times" >FoxitReaderPortable (17)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=GIMPPortable" title=" downloaded 11 times" >GIMPPortable (11)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=GoogleChromePortable" title=" downloaded 15 times" >GoogleChromePortable (15)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=GVimPortable" title=" downloaded 12 times" >GVimPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=InfraRecorder+Portable" title=" downloaded 16 times" >InfraRecorder Portable (16)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=MirandaPortable" title=" downloaded 11 times" >MirandaPortable (11)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=MozillaFirefoxPortableEdition" title=" downloaded 14 times" >MozillaFirefoxPortableEdition (14)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=MozillaThunderbirdPortableEdition" title=" downloaded 14 times" >MozillaThunderbirdPortableEdition (14)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=NotepadPortable" title=" downloaded 12 times" >NotepadPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=PidginPortable" title=" downloaded 10 times" >PidginPortable (10)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=PuTTYPortable" title=" downloaded 13 times" >PuTTYPortable (13)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=SongbirdPortable" title=" downloaded 11 times" >SongbirdPortable (11)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=SpyDLLRemoverPortable" title=" downloaded 12 times" >SpyDLLRemoverPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=SumatraPDFPortable" title=" downloaded 12 times" >SumatraPDFPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=TeamViewerPortable" title=" downloaded 12 times" >TeamViewerPortable (12)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=WinDirStatPortable" title=" downloaded 15 times" >WinDirStatPortable (15)</a><br />
<br />
<a class="downloadlink" href="http://zhuwenhao.com/wp-content/plugins/download-monitor/download.php?id=WinMergePortable" title=" downloaded 13 times" >WinMergePortable (13)</a><br /></p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/545/%e6%8a%80%e6%9c%af/%e8%87%aa%e7%94%b1%e8%bd%af%e4%bb%b6%e7%a4%be%e5%8c%ba/%e8%87%aa%e5%b7%b1%e5%8a%a8%e6%89%8b%e5%88%b6%e4%bd%9cu3p%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IEEE P802.16m标准即将结束投票</title>
		<link>http://zhuwenhao.com/498/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p802-16m%e6%a0%87%e5%87%86%e5%8d%b3%e5%b0%86%e7%bb%93%e6%9d%9f%e6%8a%95%e7%a5%a8/</link>
		<comments>http://zhuwenhao.com/498/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p802-16m%e6%a0%87%e5%87%86%e5%8d%b3%e5%b0%86%e7%bb%93%e6%9d%9f%e6%8a%95%e7%a5%a8/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 01:54:46 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[标准化工作]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/498/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p802-16m%e6%a0%87%e5%87%86%e5%8d%b3%e5%b0%86%e7%bb%93%e6%9d%9f%e6%8a%95%e7%a5%a8/</guid>
		<description><![CDATA[关于P802.16m标准
标题: IEEE本地和城域网标准 &#8211; 第16部分: 固定和移动宽带无线接入系统的空接口 &#8211; 修正案: 高级空接口   Title: IEEE Standard for Local and Metropolitan Area Networks &#8211; Part 16: Air Interface for Fixed and Mobile Broadband Wireless Access Systems &#8211; Amendment: Advanced Air Interface    Scope: This standard amends the IEEE 802.16 WirelessMAN-OFDMA specification to provide an advanced air interface ]]></description>
			<content:encoded><![CDATA[<p>关于P802.16m标准</p>
<p>标题: IEEE本地和城域网标准 &#8211; 第16部分: 固定和移动宽带无线接入系统的空接口 &#8211; 修正案: 高级空接口   <br />Title: IEEE Standard for Local and Metropolitan Area Networks &#8211; Part 16: Air Interface for Fixed and Mobile Broadband Wireless Access Systems &#8211; Amendment: Advanced Air Interface    <br />Scope: This standard amends the IEEE 802.16 WirelessMAN-OFDMA specification to provide an advanced air interface for operation in licensed bands. It meets the cellular layer requirements of IMT-Advanced next generation mobile networks. This amendment provides continuing support for legacy WirelessMAN-OFDMA equipment.    <br />Purpose: The purpose of this standard is to provide performance improvements necessary to support future advanced services and applications, such as those described by the ITU in Report ITU-R M.2072.</p>
<p>该项投票2010年7月9日结束. </p>
<p>有需要该标准文本或那个ITU2072报告的同行可以联系我. </p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/498/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p802-16m%e6%a0%87%e5%87%86%e5%8d%b3%e5%b0%86%e7%bb%93%e6%9d%9f%e6%8a%95%e7%a5%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[IEEE标准动态]]></series:name>
	</item>
		<item>
		<title>IEEE P1547.8 标准提升智能电网性能</title>
		<link>http://zhuwenhao.com/495/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p1547-8-%e6%a0%87%e5%87%86%e6%8f%90%e5%8d%87%e6%99%ba%e8%83%bd%e7%94%b5%e7%bd%91%e6%80%a7%e8%83%bd/</link>
		<comments>http://zhuwenhao.com/495/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p1547-8-%e6%a0%87%e5%87%86%e6%8f%90%e5%8d%87%e6%99%ba%e8%83%bd%e7%94%b5%e7%bd%91%e6%80%a7%e8%83%bd/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 01:35:26 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[标准化工作]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/495/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p1547-8-%e6%a0%87%e5%87%86%e6%8f%90%e5%8d%87%e6%99%ba%e8%83%bd%e7%94%b5%e7%bd%91%e6%80%a7%e8%83%bd/</guid>
		<description><![CDATA[Draft standard provides common technical platform, addresses emerging energy storage challenges in distributed   power generation, Smart Grid industries    IEEE, the world&#8217;s leading professional association for the advancement of technology today announced IEEE P1547.8,    a draft standard establishing a common technical platform for distributed resources interconnection applications. The ]]></description>
			<content:encoded><![CDATA[<p>Draft standard provides common technical platform, addresses emerging energy storage challenges in distributed   <br />power generation, Smart Grid industries    <br />IEEE, the world&#8217;s leading professional association for the advancement of technology today announced IEEE P1547.8,    <br />a draft standard establishing a common technical platform for distributed resources interconnection applications. The    <br />proposed standard expands upon IEEE 1547, while incorporating industry and National Institute of Standards and    <br />Technology (NIST) recommendations for improved interconnection performance functionality. It also addresses energy    <br />storage challenges coming into play across the distributed resources and Smart Grid industries. Ratification of IEEE P1547.8,    <br />which is sponsored by the IEEE Standards Coordinating Committee 21 (SCC21), is targeted for calendar year 2012.    <br />As a complement to the IEEE 1547 standard, IEEE P1547.8 establishes a common technical platform to address functionality    <br />for the interconnection of distributed resources across the power grid. The standard provides greater support for intermittent    <br />renewable energy sources, and more flexible use of inverters such as found in home solar power systems, enabling easier    <br />and more robust connections to the grid. It also addresses energy storage devices, hybrid generation-storage systems    <br />(ES-DER), and ES-DER aspects of plug-in electric vehicles (PEV), as well as taking into account a variety of industry-driven    <br />recommendations. IEEE P1547.8 is targeted to distributed resource owners, interconnection contractors, equipment    <br />manufacturers, system integrators, area electric power system owners, planners and operators, and regulatory agencies.    <br />In August 2009, NIST established an initial set of priority actions plans (PAPs) for developing standards necessary to build    <br />an interoperable Smart Grid. IEEE P1547.8 will support NIST PAP07 Energy Storage Interconnection Guidelines.    <br />IEEE has more than 100 standards and standards in development relevant to smart grid, including the over 20 IEEE standards    <br />named in the NIST Framework and Roadmap for Smart Grid Interoperability Standards.    <br />For more information on IEEE P1547.8, please visit <a href="http://ieeestandards.org/ct.html?rtr=on&amp;s=8nv,1e16q,2xny,kijn,m7pr,gxzm,3xa8">http://ieeestandards.org/ct.html?rtr=on&amp;s=8nv,1e16q,2xny,kijn,m7pr,gxzm,3xa8</a>    <br />For more information about IEEE’s leadership role in Smart Grid technology development, please visit the IEEE Smart Grid    <br />Web Portal at <a href="http://ieeestandards.org/ct.html?rtr=on&amp;s=8nv,1e16q,2xny,c8zn,5dek,gxzm,3xa8">http://ieeestandards.org/ct.html?rtr=on&amp;s=8nv,1e16q,2xny,c8zn,5dek,gxzm,3xa8</a>    <br />To view the complete article, please visit: <a href="http://standards.ieee.org/announcements/2010/P15478.html">http://standards.ieee.org/announcements/2010/P15478.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/495/%e6%8a%80%e6%9c%af/%e6%a0%87%e5%87%86%e5%8c%96%e5%b7%a5%e4%bd%9c/ieee-p1547-8-%e6%a0%87%e5%87%86%e6%8f%90%e5%8d%87%e6%99%ba%e8%83%bd%e7%94%b5%e7%bd%91%e6%80%a7%e8%83%bd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[IEEE标准动态]]></series:name>
	</item>
		<item>
		<title>修改主题支持两种菜单并存</title>
		<link>http://zhuwenhao.com/480/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e4%bf%ae%e6%94%b9%e4%b8%bb%e9%a2%98%e6%94%af%e6%8c%81%e4%b8%a4%e7%a7%8d%e8%8f%9c%e5%8d%95%e5%b9%b6%e5%ad%98/</link>
		<comments>http://zhuwenhao.com/480/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e4%bf%ae%e6%94%b9%e4%b8%bb%e9%a2%98%e6%94%af%e6%8c%81%e4%b8%a4%e7%a7%8d%e8%8f%9c%e5%8d%95%e5%b9%b6%e5%ad%98/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 15:13:17 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[服务器和网站类]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=480</guid>
		<description><![CDATA[在本站升级到Wordpress 3.0后，浏览了一下许久没有看过的themes目录，发现几个我喜欢的主题，经过一番试用，发现Mystique也就是您现在看到的主题最合我心意，后来才发现这也是digitalnature的作品，good job！
美中不足的是，Mystique配置界面中主菜单只能在无、链接、页面、分类目录和自定义菜单中做单选，我希望能把分类目录和自定义菜单并存，一起显示出来。可惜作者没有设计这样的功能。Hacking的真谛就是要自己动手，当然还有无私分享。下面我就贴出我的做法：
先来看看core.php中相关功能实现函数

View Code PHP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// print the main navigation menu
function mystique_navigation&#40;&#41; &#123;
  $navtype = get_mystique_option&#40;'navigation'&#41;;
  if&#40;$navtype&#41;: ?&#62;
&#160;
   &#60;div class=&#34;shadow-left&#34;&#62;
   &#60;div class=&#34;shadow-right clearfix&#34;&#62;
   &#60;?php
    $nav_extra = apply_filters&#40;&#34;mystique_navigation_extra&#34;, ''&#41;;  // check for new icons and output
    if&#40;$nav_extra&#41; echo '&#60;p class=&#34;nav-extra&#34;&#62;'.$nav_extra.'&#60;/p&#62;';  ?&#62;
&#160;
 ]]></description>
			<content:encoded><![CDATA[<p>在本站升级到Wordpress 3.0后，浏览了一下许久没有看过的themes目录，发现几个我喜欢的主题，经过一番试用，发现Mystique也就是您现在看到的主题最合我心意，后来才发现这也是digitalnature的作品，good job！</p>
<p>美中不足的是，Mystique配置界面中主菜单只能在无、链接、页面、分类目录和自定义菜单中做单选，我希望能把分类目录和自定义菜单并存，一起显示出来。可惜作者没有设计这样的功能。Hacking的真谛就是要自己动手，当然还有无私分享。下面我就贴出我的做法：</p>
<p>先来看看core.php中相关功能实现函数</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p480code5'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4805"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
</pre></td><td class="code" id="p480code5"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// print the main navigation menu</span>
<span style="color: #000000; font-weight: bold;">function</span> mystique_navigation<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$navtype</span> <span style="color: #339933;">=</span> get_mystique_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'navigation'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
   <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;shadow-left&quot;</span><span style="color: #339933;">&gt;</span>
   <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;shadow-right clearfix&quot;</span><span style="color: #339933;">&gt;</span>
   <span style="color: #000000; font-weight: bold;">&lt;?php</span>
    <span style="color: #000088;">$nav_extra</span> <span style="color: #339933;">=</span> apply_filters<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mystique_navigation_extra&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// check for new icons and output</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nav_extra</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;p class=&quot;nav-extra&quot;&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$nav_extra</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>  <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
   <span style="color: #339933;">&lt;</span>ul id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;navigation&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;clearfix&quot;</span><span style="color: #339933;">&gt;</span>
     <span style="color: #000000; font-weight: bold;">&lt;?php</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>get_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'show_on_front'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&lt;&gt;</span><span style="color: #0000ff;">'page'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> get_mystique_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exclude_home'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&lt;&gt;</span><span style="color: #0000ff;">'1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
       <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>is_home<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>is_paged<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #339933;">&lt;</span>li <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;active home&quot;</span><span style="color: #339933;">&gt;&lt;</span>a <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;home active fadeThis&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo get_settings('home'); ?&gt;&quot;</span> title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php _e('You are Home','mystique'); ?&gt;&quot;</span><span style="color: #339933;">&gt;&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Home'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'mystique'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pointer&quot;</span><span style="color: #339933;">&gt;&lt;/</span>span<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>li<span style="color: #339933;">&gt;</span>
       <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #339933;">&lt;</span>li <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;home&quot;</span><span style="color: #339933;">&gt;&lt;</span>a <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;home fadeThis&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo get_option('home'); ?&gt;&quot;</span> title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php _e('Click for Home','mystique'); ?&gt;&quot;</span><span style="color: #339933;">&gt;&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Home'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'mystique'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pointer&quot;</span><span style="color: #339933;">&gt;&lt;/</span>span<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>li<span style="color: #339933;">&gt;</span>
      <span style="color: #000000; font-weight: bold;">&lt;?php</span>
       <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
     <span style="color: #000000; font-weight: bold;">&lt;?php</span>
       <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
        mystique_list_categories<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hide_empty'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'exclude'</span> <span style="color: #339933;">=&gt;</span> get_mystique_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exclude_categories'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
        <span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> get_bookmarks<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'orderby'</span>        <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'name'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'order'</span>          <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ASC'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'limit'</span>          <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'category'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'category_name'</span>  <span style="color: #339933;">=&gt;</span> get_mystique_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'navigation_links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'hide_invisible'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'show_updated'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'include'</span>        <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'search'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
         <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_target</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$target</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">' target=&quot;'</span><span style="color: #339933;">.</span>wp_specialchars<span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_target</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">else</span> <span style="color: #000088;">$target</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_rel</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$rel</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">' rel=&quot;'</span><span style="color: #339933;">.</span>wp_specialchars<span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_rel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">else</span> <span style="color: #000088;">$rel</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_description</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">' title=&quot;'</span><span style="color: #339933;">.</span>wp_specialchars<span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_description</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">else</span> <span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;li&gt;&lt;a class=&quot;fadeThis&quot; href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_url</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$target</span><span style="color: #339933;">.</span><span style="color: #000088;">$rel</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&gt;&lt;span class=&quot;title&quot;&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link_name</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/span&gt;&lt;span class=&quot;pointer&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;li&gt;'</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span>
        mystique_list_pages<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exclude'</span> <span style="color: #339933;">=&gt;</span> get_mystique_option<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exclude_pages'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sort_column'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'menu_order'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
       <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
&nbsp;
       do_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mystique_navigation'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
   <span style="color: #339933;">&lt;/</span>ul<span style="color: #339933;">&gt;</span>
   <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
   <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>可以看出，作者整体设计的时候，就没有想要让用户做复选，在条件判断中使用了连续的if &#8230; elseif&#8230; 实现。</p>
<p>我采用了一个偷懒的方法仅把</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p480code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4806"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p480code6"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span></pre></td></tr></table></div>

<p>注释掉，然后把接下来的</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p480code7'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4807"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p480code7"><pre class="php" style="font-family:monospace;"> <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span></pre></td></tr></table></div>

<p>改成</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p480code8'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4808"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p480code8"><pre class="php" style="font-family:monospace;"> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$navtype</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'links'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span></pre></td></tr></table></div>

<p>就可以啦。</pre>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/480/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e4%bf%ae%e6%94%b9%e4%b8%bb%e9%a2%98%e6%94%af%e6%8c%81%e4%b8%a4%e7%a7%8d%e8%8f%9c%e5%8d%95%e5%b9%b6%e5%ad%98/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C语言嵌入式系统编程修炼之二:软件架构篇</title>
		<link>http://zhuwenhao.com/411/%e6%8a%80%e6%9c%af/%e8%bd%af%e4%bb%b6%e5%b7%a5%e7%a8%8b/%e8%ae%be%e8%ae%a1/c%e8%af%ad%e8%a8%80%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f%e7%bc%96%e7%a8%8b%e4%bf%ae%e7%82%bc%e4%b9%8b%e4%ba%8c%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84%e7%af%87/</link>
		<comments>http://zhuwenhao.com/411/%e6%8a%80%e6%9c%af/%e8%bd%af%e4%bb%b6%e5%b7%a5%e7%a8%8b/%e8%ae%be%e8%ae%a1/c%e8%af%ad%e8%a8%80%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f%e7%bc%96%e7%a8%8b%e4%bf%ae%e7%82%bc%e4%b9%8b%e4%ba%8c%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84%e7%af%87/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 06:19:06 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[设计]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=411</guid>
		<description><![CDATA[作者：宋宝华　来源：天极网
朱文昊按语: 最近读到的一篇文章,收藏并作为一篇程序员修炼之路专辑中的一篇文章.
模块划分
 
模块划分的&#8221;划&#8221;是规划的意思，意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言，在模块的划分上主要依据功能（依功能进行划分在面向对象设计中成为一个错误，牛顿定律遇到了相对论），C语言模块化程序设计需理解如下概念：
（1） 模块即是一个.c文件和一个.h文件的结合，头文件(.h)中是对于该模块接口的声明；
（2） 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明；
（3） 模块内的函数和全局变量需在.c文件开头冠以static关键字声明；
（4） 永远不要在.h文件中定义变量！定义变量和声明变量的区别在于定义会产生内存分配的操作，是汇编阶段的概念；而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如：



/*module1.h*/
int a = 5; /* 在模块1的.h文件中定义int a */
/*module1 .c*/
#include &#8220;module1.h&#8221; /* 在模块1中包含模块1的.h文件 */
/*module2 .c*/
#include &#8220;module1.h&#8221; /* 在模块2中包含模块1的.h文件 */
/*module3 .c*/
#include &#8220;module1.h&#8221; /* 在模块3中包含模块1的.h文件 */



以上程序的结果是在模块1、2、3中都定义了整型变量a，a在不同的模块中对应不同的地址单元，这个世界上从来不需要这样的程序。正确的做法是：



/*module1.h*/
extern int a; /* 在模块1的.h文件中声明int a */
/*module1 .c*/
#include &#8220;module1.h&#8221; /* 在模块1中包含模块1的.h文件 */
int a = 5; /* 在模块1的.c文件中定义int a */
/*module2 .c*/
#include &#8220;module1.h&#8221; /* 在模块2中包含模块1的.h文件 */
/*module3 .c*/
#include &#8220;module1.h&#8221; /* ]]></description>
			<content:encoded><![CDATA[<p>作者：宋宝华　来源：天极网</p>
<p>朱文昊按语: 最近读到的一篇文章,收藏并作为一篇程序员修炼之路专辑中的一篇文章.</p>
<p><strong>模块划分</strong></p>
<p><strong> </strong></p>
<p>模块划分的&#8221;划&#8221;是规划的意思，意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言，在模块的划分上主要依据功能（依功能进行划分在面向对象设计中成为一个错误，牛顿定律遇到了相对论），C语言模块化程序设计需理解如下概念：</p>
<p>（1） 模块即是一个.c文件和一个.h文件的结合，头文件(.h)中是对于该模块接口的声明；</p>
<p>（2） 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明；</p>
<p>（3） 模块内的函数和全局变量需在.c文件开头冠以static关键字声明；</p>
<p>（4） 永远不要在.h文件中定义变量！定义变量和声明变量的区别在于定义会产生内存分配的操作，是汇编阶段的概念；而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>/*module1.h*/<br />
int a = 5; /* 在模块1的.h文件中定义int a */</p>
<p>/*module1 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块1中包含模块1的.h文件 */</p>
<p>/*module2 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块2中包含模块1的.h文件 */</p>
<p>/*module3 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块3中包含模块1的.h文件 */</td>
</tr>
</tbody>
</table>
<p>以上程序的结果是在模块1、2、3中都定义了整型变量a，a在不同的模块中对应不同的地址单元，这个世界上从来不需要这样的程序。正确的做法是：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>/*module1.h*/<br />
extern int a; /* 在模块1的.h文件中声明int a */</p>
<p>/*module1 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块1中包含模块1的.h文件 */<br />
int a = 5; /* 在模块1的.c文件中定义int a */</p>
<p>/*module2 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块2中包含模块1的.h文件 */</p>
<p>/*module3 .c*/<br />
#include &#8220;module1.h&#8221; /* 在模块3中包含模块1的.h文件 */</td>
</tr>
</tbody>
</table>
<p>这样如果模块1、2、3操作a的话，对应的是同一片内存单元。</p>
<p>一个嵌入式系统通常包括两类模块：</p>
<p>（1）硬件驱动模块，一种特定硬件对应一个模块；</p>
<p>（2）软件功能模块，其模块的划分应满足低偶合、高内聚的要求。</p>
<p><strong>多任务还是单任务</strong></p>
<p>所谓&#8221;单任务系统&#8221;是指该系统不能支持多任务并发操作，宏观串行地执行一个任务。而多任务系统则可以宏观并行（微观上可能串行）地&#8221;同时&#8221;执行多个任务。</p>
<p>多任务的并发执行通常依赖于一个多任务操作系统（OS），多任务OS的核心是系统调度器，它使用任务控制块（TCB）来管理任务调度功能。TCB包括任务的当前状态、优先级、要等待的事件或资源、任务程序码的起始地址、初始堆栈指针等信息。调度器在任务被激活时，要用到这些信息。此外，TCB还被用来存放任务的&#8221;上下文&#8221;（context)。任务的上下文就是当一个执行中的任务被停止时，所要保存的所有信息。通常，上下文就是计算机当前的状态，也即各个寄存器的内容。当发生任务切换时，当前运行的任务的上下文被存入TCB，并将要被执行的任务的上下文从它的TCB中取出，放入各个寄存器中。</p>
<p>嵌入式多任务OS的典型例子有Vxworks、ucLinux等。嵌入式OS并非遥不可及的神坛之物，我们可以用不到1000行代码实现一个针对80186处理器的功能最简单的OS内核，作者正准备进行此项工作，希望能将心得贡献给大家。</p>
<p>究竟选择多任务还是单任务方式，依赖于软件的体系是否庞大。例如，绝大多数手机程序都是多任务的，但也有一些小灵通的协议栈是单任务的，没有操作系统，它们的主程序轮流调用各个软件模块的处理程序，模拟多任务环境。</p>
<p><span id="more-411"></span></p>
<p><strong>单任务程序典型架构</strong></p>
<p><strong> </strong></p>
<p>（1）从CPU复位时的指定地址开始执行；</p>
<p>（2）跳转至汇编代码startup处执行；</p>
<p>（3）跳转至用户主程序main执行，在main中完成：</p>
<p>a.初试化各硬件设备；</p>
<p>b.初始化各软件模块；</p>
<p>c.进入死循环（无限循环），调用各模块的处理函数</p>
<p>用户主程序和各模块的处理函数都以C语言完成。用户主程序最后都进入了一个死循环，其首选方案是：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>while(1)<br />
{<br />
}</td>
</tr>
</tbody>
</table>
<p>有的程序员这样写：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>for(;;)<br />
{<br />
}</td>
</tr>
</tbody>
</table>
<p>这个语法没有确切表达代码的含义，我们从for(;;)看不出什么，只有弄明白for(;;)在C语言中意味着无条件循环才明白其意。</p>
<p>下面是几个&#8221;著名&#8221;的死循环：</p>
<p>（1）操作系统是死循环；</p>
<p>（2）WIN32程序是死循环；</p>
<p>（3）嵌入式系统软件是死循环；</p>
<p>（4）多线程程序的线程处理函数是死循环。</p>
<p>你可能会辩驳，大声说：&#8221;凡事都不是绝对的，2、3、4都可以不是死循环&#8221;。Yes，you are right，但是你得不到鲜花和掌声。实际上，这是一个没有太大意义的牛角尖，因为这个世界从来不需要一个处理完几个消息就喊着要OS杀死它的WIN32程序，不需要一个刚开始RUN就自行了断的嵌入式系统，不需要莫名其妙启动一个做一点事就干掉自己的线程。有时候，过于严谨制造的不是便利而是麻烦。君不见，五层的TCP/IP协议栈超越严谨的ISO/OSI七层协议栈大行其道成为事实上的标准？</p>
<p>经常有网友讨论：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>printf(&#8220;%d,%d&#8221;,++i,i++); /* 输出是什么？*/<br />
c = a+++b; /* c=? */</td>
</tr>
</tbody>
</table>
<p>等类似问题。面对这些问题，我们只能发出由衷的感慨：世界上还有很多有意义的事情等着我们去消化摄入的食物。</p>
<p>实际上，嵌入式系统要运行到世界末日。</p>
<p><strong>中断服务程序</strong></p>
<p>中断是嵌入式系统中重要的组成部分，但是在标准C中不包含中断。许多编译开发商在标准C上增加了对中断的支持，提供新的关键字用于标示中断服务程序(ISR)，类似于__interrupt、#program interrupt等。当一个函数被定义为ISR的时候，编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。</p>
<p>中断服务程序需要满足如下要求：</p>
<p>(1)不能返回值；</p>
<p>(2)不能向ISR传递参数；</p>
<p>(3) ISR应该尽可能的短小精悍；</p>
<p>(4) printf(char * lpFormatString,…)函数会带来重入和性能问题，不能在ISR中采用。</p>
<p>在某项目的开发中，我们设计了一个队列，在中断服务程序中，只是将中断类型添加入该队列中，在主程序的死循环中不断扫描中断队列是否有中断，有则取出队列中的第一个中断类型，进行相应处理。</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>/* 存放中断的队列 */<br />
typedef struct tagIntQueue<br />
{<br />
int intType; /* 中断类型 */<br />
struct tagIntQueue *next;<br />
}IntQueue;</p>
<p>IntQueue lpIntQueueHead;</p>
<p>__interrupt ISRexample ()<br />
{<br />
int intType;<br />
intType = GetSystemType();<br />
QueueAddTail(lpIntQueueHead, intType)；/* 在队列尾加入新的中断 */<br />
}</td>
</tr>
</tbody>
</table>
<p>在主程序循环中判断是否有中断：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>While(1)<br />
{<br />
If( !IsIntQueueEmpty() )<br />
{<br />
intType = GetFirstInt();<br />
switch(intType) /* 是不是很象WIN32程序的消息解析函数? */<br />
{<br />
/* 对，我们的中断类型解析很类似于消息驱动 */<br />
case xxx: /* 我们称其为&#8221;中断驱动&#8221;吧？ */<br />
…<br />
break;<br />
case xxx:<br />
…<br />
break;<br />
…<br />
}<br />
}<br />
}</td>
</tr>
</tbody>
</table>
<p>按上述方法设计的中断服务程序很小，实际的工作都交由主程序执行了。</p>
<p><strong>硬件驱动模块</strong></p>
<p><strong> </strong></p>
<p>一个硬件驱动模块通常应包括如下函数：</p>
<p>（1）中断服务程序ISR</p>
<p>（2）硬件初始化</p>
<p>a.修改寄存器，设置硬件参数（如UART应设置其波特率，AD/DA设备应设置其采样速率等）；</p>
<p>b.将中断服务程序入口地址写入中断向量表：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>/* 设置中断向量表 */<br />
m_myPtr = make_far_pointer(0l); /* 返回void far型指针void far * */<br />
m_myPtr += ITYPE_UART; /* ITYPE_UART： uart中断服务程序 */<br />
/* 相对于中断向量表首地址的偏移 */<br />
*m_myPtr = &amp;UART _Isr; /* UART _Isr：UART的中断服务程序 */</td>
</tr>
</tbody>
</table>
<p>（3）设置CPU针对该硬件的控制线</p>
<p>a.如果控制线可作PIO（可编程I/O）和控制信号用，则设置CPU内部对应寄存器使其作为控制信号；</p>
<p>b.设置CPU内部的针对该设备的中断屏蔽位，设置中断方式（电平触发还是边缘触发）。</p>
<p>（4）提供一系列针对该设备的操作接口函数。例如，对于LCD，其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数；而对于实时钟，其驱动模块则需提供获取时间、设置时间等函数。</p>
<p><strong>C的面向对象化</strong></p>
<p>在面向对象的语言里面，出现了类的概念。类是对特定数据的特定操作的集合体。类包含了两个范畴：数据和操作。而C语言中的struct仅仅是数据的集合，我们可以利用函数指针将struct模拟为一个包含数据和操作的&#8221;类&#8221;。下面的C程序模拟了一个最简单的&#8221;类&#8221;：</p>
<table border="1" width="90%" align="center" bgcolor="#dadacf" bordercolor="#ffcc66">
<tbody>
<tr>
<td>#ifndef C_Class<br />
#define C_Class struct<br />
#endif<br />
C_Class A<br />
{<br />
C_Class A *A_this; /* this指针 */<br />
void (*Foo)(C_Class A *A_this); /* 行为：函数指针 */<br />
int a; /* 数据 */<br />
int b;<br />
};</td>
</tr>
</tbody>
</table>
<p>我们可以利用C语言模拟出面向对象的三个特性：封装、继承和多态，但是更多的时候，我们只是需要将数据与行为封装以解决软件结构混乱的问题。C模拟面向对象思想的目的不在于模拟行为本身，而在于解决某些情况下使用C语言编程时程序整体框架结构分散、数据和函数脱节的问题。我们在后续章节会看到这样的例子。</p>
<p><strong>总结</strong></p>
<p>本篇介绍了嵌入式系统编程软件架构方面的知识，主要包括模块划分、多任务还是单任务选取、单任务程序典型架构、中断服务程序、硬件驱动模块设计等，从宏观上给出了一个嵌入式系统软件所包含的主要元素。</p>
<p>请记住：软件结构是软件的灵魂！结构混乱的程序面目可憎，调试、测试、维护、升级都极度困难。</p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/411/%e6%8a%80%e6%9c%af/%e8%bd%af%e4%bb%b6%e5%b7%a5%e7%a8%8b/%e8%ae%be%e8%ae%a1/c%e8%af%ad%e8%a8%80%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f%e7%bc%96%e7%a8%8b%e4%bf%ae%e7%82%bc%e4%b9%8b%e4%ba%8c%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84%e7%af%87/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[程序员修炼之路]]></series:name>
	</item>
		<item>
		<title>GPS探测运动</title>
		<link>http://zhuwenhao.com/406/%e6%8a%80%e6%9c%af/%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f/%e4%bc%a0%e6%84%9f%e5%99%a8/gps%e6%8e%a2%e6%b5%8b%e8%bf%90%e5%8a%a8/</link>
		<comments>http://zhuwenhao.com/406/%e6%8a%80%e6%9c%af/%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f/%e4%bc%a0%e6%84%9f%e5%99%a8/gps%e6%8e%a2%e6%b5%8b%e8%bf%90%e5%8a%a8/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 13:34:34 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[传感器]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=406</guid>
		<description><![CDATA[GPS可以作为探测运动和观测变化世界的绝佳工具。
如果用GPS接收器对某一固定点连续读取数据的话，就可以追踪这一点的运动情况，例如火山在内部岩浆作用下的不断膨胀，或是从南极大陆架上断裂下来的冰山的移动情况。增加接收器的数量（提高精度），用已知精确位置的GPS固定基站的信号作为基准，就可以清晰地捕捉到物体1／10英寸的突然运动，并对其进行实时监测。有了这项技术，科学家们就可以“上天入地”，探索很多我们原来并不十分清楚的动态过程。
香港的青马大桥是世界上最长的悬索桥，全长2200米，主桥跨度达1377米，两座吊塔高206米，距离海面62米。大桥可以承受强烈台风的袭击，桥体摇动距离可以达到几英尺，而疾驰而过的列车也会造成大桥主跨产生上下半米左右的振动。不过大桥的摇动也不能过于剧烈，如果桥身侧摆超过5米，大桥的钢梁和吊索就会像面条一样发生扭曲和弯折。

为了防患于未然，监测青马大桥的工程技术人员采用了GPS传感器阵列来对大桥的三维空间位置进行实时监控。他们在大桥的吊索、桥面和桥塔上安装了14个GPS接收器，这些接收器用长达数公里的光缆相连。这些传感器每秒钟都会向中央主控计算机发送10次各自的空间位置信息。同时在另外两个固定点上安装的GPS传感器也向主控计算机发回数据，主控计算机对数据进行校正以减小其误差。这样就可以把大桥的空间位置精确地显示出来，其水平误差不超过1厘米，垂直误差不超过2厘米。计算机还可以计算出风速和风向，并估算出大桥各个部位的应力和载荷状况，这样维护人员就可以方便地安排修理和维护工作。
科学家们还从来没有实地观察过金星或其他星球上的火山爆发。他们只知道在远古时代那里曾经有过火山爆发，但是对岩浆的流动速度、粘稠度等许多具体情况却无从得知。现在也没有能够在金星表面进行实地勘测的设备。于是科学家们就只能寻找地球上与之相类似的物质进行替代研究，然后把地球表面的物质与卫星照片进行对照，再分析其它星球的卫星照片，以此来分析推断遥远星球的情况。
在观察地球卫星照片的时候，科学家们发现美国新墨西哥州两处长达40到50公里的岩浆流，地理学家给它们起名为Car－rizozo和McCartys。这么长的岩浆流在地球上实属罕见，但在金星上却是很典型的情况。金星上的温度要比地球高得多，岩浆流的长度和存留时间要比地球上更长。
研究人员搜集了有关这两处岩浆流的几千份GPS数据，建立了岩浆流在许多不同地点的精确地形剖面图资料。这些岩浆流经地段的高度、坡度等地形资料能够帮助地质学家们了解岩浆的粘稠度，从而也就能判断出岩浆的成份及其流动的速度。Carrizozo和McCartys这两处岩浆流中间部分的粘稠度较低，而边缘部分粘稠度则较大，所以这两处岩浆流的特点就是中间流速大、不易冷却，边缘流速慢、冷却速度快。GPS数据还显示了凝固的岩浆外壳下隐藏着的奇异现象，其中包括岩浆流中心的一条岩浆管道，这一管道可以使岩浆在长达15公里的距离内保持融化状态。研究人员目前还不知道金星上是否也存在这种岩浆管道，这是一项很吸引人的研究内容。如果没有GPS的高精度测量技术，研究人员或许根本不会去研究这个问题，了解这一切的唯一途径就是亲自深入险地进行观测，但即使研究人员呆在火山爆发的地方亲自观察也未必能有这样的发现。
GPS系统在很多领域都获得了广泛的应用，它的功能现在已经不仅仅局限于为个人提供位置和时间信息了。拥有这项技术，我们向宇宙的真相又迈进了一步。GPS系统的未来无可限量，技术进步带来的梦想也是没有止境的。
]]></description>
			<content:encoded><![CDATA[<p>GPS可以作为探测运动和观测变化世界的绝佳工具。</p>
<p>如果用GPS接收器对某一固定点连续读取数据的话，就可以追踪这一点的运动情况，例如火山在内部岩浆作用下的不断膨胀，或是从南极大陆架上断裂下来的冰山的移动情况。增加接收器的数量（提高精度），用已知精确位置的GPS固定基站的信号作为基准，就可以清晰地捕捉到物体1／10英寸的突然运动，并对其进行实时监测。有了这项技术，科学家们就可以“上天入地”，探索很多我们原来并不十分清楚的动态过程。</p>
<p><span style="font-size: 13.3333px;">香港的青马大桥是世界上最长的悬索桥，全长2200米，主桥跨度达1377米，两座吊塔高206米，距离海面62米。大桥可以承受强烈台风的袭击，桥体摇动距离可以达到几英尺，而疾驰而过的列车也会造成大桥主跨产生上下半米左右的振动。不过大桥的摇动也不能过于剧烈，如果桥身侧摆超过5米，大桥的钢梁和吊索就会像面条一样发生扭曲和弯折。</span></p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/HLIC/63826adc76afb49fdf0d40c53d63e534.jpg"></a><a href="http://zhuwenhao.com/wp-content/uploads/HLIC/63826adc76afb49fdf0d40c53d63e534.jpg"></a><a href="http://zhuwenhao.com/wp-content/uploads/HLIC/63826adc76afb49fdf0d40c53d63e534.jpg"></a></p>
<p>为了防患于未然，监测青马大桥的工程技术人员采用了GPS传感器阵列来对大桥的三维空间位置进行实时监控。他们在大桥的吊索、桥面和桥塔上安装了14个GPS接收器，这些接收器用长达数公里的光缆相连。这些传感器每秒钟都会向中央主控计算机发送10次各自的空间位置信息。同时在另外两个固定点上安装的GPS传感器也向主控计算机发回数据，主控计算机对数据进行校正以减小其误差。这样就可以把大桥的空间位置精确地显示出来，其水平误差不超过1厘米，垂直误差不超过2厘米。计算机还可以计算出风速和风向，并估算出大桥各个部位的应力和载荷状况，这样维护人员就可以方便地安排修理和维护工作。</p>
<p>科学家们还从来没有实地观察过金星或其他星球上的火山爆发。他们只知道在远古时代那里曾经有过火山爆发，但是对岩浆的流动速度、粘稠度等许多具体情况却无从得知。现在也没有能够在金星表面进行实地勘测的设备。于是科学家们就只能寻找地球上与之相类似的物质进行替代研究，然后把地球表面的物质与卫星照片进行对照，再分析其它星球的卫星照片，以此来分析推断遥远星球的情况。</p>
<p>在观察地球卫星照片的时候，科学家们发现美国新墨西哥州两处长达40到50公里的岩浆流，地理学家给它们起名为Car－rizozo和McCartys。这么长的岩浆流在地球上实属罕见，但在金星上却是很典型的情况。金星上的温度要比地球高得多，岩浆流的长度和存留时间要比地球上更长。</p>
<p>研究人员搜集了有关这两处岩浆流的几千份GPS数据，建立了岩浆流在许多不同地点的精确地形剖面图资料。这些岩浆流经地段的高度、坡度等地形资料能够帮助地质学家们了解岩浆的粘稠度，从而也就能判断出岩浆的成份及其流动的速度。Carrizozo和McCartys这两处岩浆流中间部分的粘稠度较低，而边缘部分粘稠度则较大，所以这两处岩浆流的特点就是中间流速大、不易冷却，边缘流速慢、冷却速度快。GPS数据还显示了凝固的岩浆外壳下隐藏着的奇异现象，其中包括岩浆流中心的一条岩浆管道，这一管道可以使岩浆在长达15公里的距离内保持融化状态。研究人员目前还不知道金星上是否也存在这种岩浆管道，这是一项很吸引人的研究内容。如果没有GPS的高精度测量技术，研究人员或许根本不会去研究这个问题，了解这一切的唯一途径就是亲自深入险地进行观测，但即使研究人员呆在火山爆发的地方亲自观察也未必能有这样的发现。</p>
<p><span style="font-size: 13.3333px;">GPS系统在很多领域都获得了广泛的应用，它的功能现在已经不仅仅局限于为个人提供位置和时间信息了。拥有这项技术，我们向宇宙的真相又迈进了一步。GPS系统的未来无可限量，技术进步带来的梦想也是没有止境的。</span></p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/406/%e6%8a%80%e6%9c%af/%e5%b5%8c%e5%85%a5%e5%bc%8f%e7%b3%bb%e7%bb%9f/%e4%bc%a0%e6%84%9f%e5%99%a8/gps%e6%8e%a2%e6%b5%8b%e8%bf%90%e5%8a%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>剖析Linux系统启动过程</title>
		<link>http://zhuwenhao.com/391/%e6%8a%80%e6%9c%af/%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f%e4%bd%bf%e7%94%a8/%e5%89%96%e6%9e%90linux%e7%b3%bb%e7%bb%9f%e5%90%af%e5%8a%a8%e8%bf%87%e7%a8%8b/</link>
		<comments>http://zhuwenhao.com/391/%e6%8a%80%e6%9c%af/%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f%e4%bd%bf%e7%94%a8/%e5%89%96%e6%9e%90linux%e7%b3%bb%e7%bb%9f%e5%90%af%e5%8a%a8%e8%bf%87%e7%a8%8b/#comments</comments>
		<pubDate>Sat, 15 May 2010 13:36:25 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[操作系统使用]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=391</guid>
		<description><![CDATA[当用户打开PC的电源，BIOS开机自检，按BIOS中设置的启动设备(通常是硬盘)启动，接着启动设备上安装的引导程序lilo或grub开始引导Linux，Linux首先进行内核的引导，接下来执行init程序，init程序调用了rc.sysinit和rc等程序，rc.sysinit和rc当完成系统初始化和运行服务的任务后，返回init；init启动了mingetty后，打开了终端供用户登录系统，用户登录成功后进入了Shell，这样就完成了从开机到登录的整个启动过程。

下面就将逐一介绍其中几个关键的部分：
第一部分：内核的引导(核内引导)
Red Hat9.0可以使用lilo或grub等引导程序开始引导Linux系统，当引导程序成功完成引导任务后，Linux从它们手中接管了CPU的控制权，然后CPU就开始执行Linux的核心映象代码，开始了Linux启动过程。这里使用了几个汇编程序来引导Linux，这一步泛及到Linux源代码树中的“arch/i386/boot”下的这几个文件：bootsect.S、setup.S、video.S等。
其中bootsect.S是生成引导扇区的汇编源码，它完成加载动作后直接跳转到setup.S的程序入口。setup.S的主要功能就是将系统参数（包括内存、磁盘等，由BIOS返回）拷贝到特别内存中，以便以后这些参数被保护模式下的代码来读取。此外，setup.S还将video.S中的代码包含进来，检测和设置显示器和显示模式。最后，setup.S将系统转换到保护模式，并跳转到 0&#215;100000。
那么0&#215;100000这个内存地址中存放的是什么代码？而这些代码又是从何而来的呢？
0&#215;100000这个内存地址存放的是解压后的内核，因为Red Hat提供的内核包含了众多驱动和功能而显得比较大，所以在内核编译中使用了“makebzImage”方式，从而生成压缩过的内核，在RedHat中内核常常被命名为vmlinuz，在Linux的最初引导过程中，是通过&#8221;arch/i386/boot/compressed/&#8221;中的head.S利用misc.c中定义的decompress_kernel()函数，将内核vmlinuz解压到0&#215;100000的。
当CPU跳到0&#215;100000时，将执行&#8221;arch/i386/kernel/head.S&#8221;中的startup_32，它也是vmlinux的入口，然后就跳转到start_kernel()中去了。start_kernel()是&#8221;init/main.c&#8221;中的定义的函数，start_kernel()中调用了一系列初始化函数，以完成kernel本身的设置。start_kernel()函数中，做了大量的工作来建立基本的Linux核心环境。如果顺利执行完start_kernel()，则基本的Linux核心环境已经建立起来了。
在start_kernel()的最后，通过调用init()函数，系统创建第一个核心线程，启动了init过程。而核心线程init()主要是来进行一些外设初始化的工作的，包括调用do_basic_setup()完成外设及其驱动程序的加载和初始化。并完成文件系统初始化和root文件系统的安装。
当do_basic_setup()函数返回init()，init()又打开了/dev/console设备，重定向三个标准的输入输出文件stdin、stdout和stderr到控制台，最后，搜索文件系统中的init程序（或者由init=命令行参数指定的程序），并使用 execve()系统调用加载执行init程序。到此init()函数结束，内核的引导部分也到此结束了.

第二部分：运行init
init的进程号是1，从这一点就能看出，init进程是系统所有进程的起点，Linux在完成核内引导以后，就开始运行init程序，。init程序需要读取配置文件/etc/inittab。inittab是一个不可执行的文本文件，它有若干行指令所组成。在Redhat系统中，inittab的内容如下所示(以“###&#8221;开始的中注释为笔者增加的)：

View Code BASH1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#
# inittab       This file describes how the INIT process should set up
#               the system in a certain run-level.
#
# Author:       Miquel van Smoorenburg,
&#160;
#               Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
&#160;
# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   ]]></description>
			<content:encoded><![CDATA[<p>当用户打开PC的电源，BIOS开机自检，按BIOS中设置的启动设备(通常是硬盘)启动，接着启动设备上安装的引导程序lilo或grub开始引导Linux，Linux首先进行内核的引导，接下来执行init程序，init程序调用了rc.sysinit和rc等程序，rc.sysinit和rc当完成系统初始化和运行服务的任务后，返回init；init启动了mingetty后，打开了终端供用户登录系统，用户登录成功后进入了Shell，这样就完成了从开机到登录的整个启动过程。</p>
<p><a href="http://zhuwenhao.com/wp-content/uploads/HLIC/bf8c26af4fc2b4e702fa856e9938e06d.jpg"><img class="alignnone" title="Linux系统启动过程" src="http://zhuwenhao.com/wp-content/uploads/HLIC/bf8c26af4fc2b4e702fa856e9938e06d.jpg" alt="Linux系统启动过程" width="343" height="450" /></a></p>
<p>下面就将逐一介绍其中几个关键的部分：<br />
第一部分：内核的引导(核内引导)</p>
<p>Red Hat9.0可以使用lilo或grub等引导程序开始引导Linux系统，当引导程序成功完成引导任务后，Linux从它们手中接管了CPU的控制权，然后CPU就开始执行Linux的核心映象代码，开始了Linux启动过程。这里使用了几个汇编程序来引导Linux，这一步泛及到Linux源代码树中的“arch/i386/boot”下的这几个文件：bootsect.S、setup.S、video.S等。</p>
<p>其中bootsect.S是生成引导扇区的汇编源码，它完成加载动作后直接跳转到setup.S的程序入口。setup.S的主要功能就是将系统参数（包括内存、磁盘等，由BIOS返回）拷贝到特别内存中，以便以后这些参数被保护模式下的代码来读取。此外，setup.S还将video.S中的代码包含进来，检测和设置显示器和显示模式。最后，setup.S将系统转换到保护模式，并跳转到 0&#215;100000。</p>
<p>那么0&#215;100000这个内存地址中存放的是什么代码？而这些代码又是从何而来的呢？</p>
<p>0&#215;100000这个内存地址存放的是解压后的内核，因为Red Hat提供的内核包含了众多驱动和功能而显得比较大，所以在内核编译中使用了“makebzImage”方式，从而生成压缩过的内核，在RedHat中内核常常被命名为vmlinuz，在Linux的最初引导过程中，是通过&#8221;arch/i386/boot/compressed/&#8221;中的head.S利用misc.c中定义的decompress_kernel()函数，将内核vmlinuz解压到0&#215;100000的。</p>
<p>当CPU跳到0&#215;100000时，将执行&#8221;arch/i386/kernel/head.S&#8221;中的startup_32，它也是vmlinux的入口，然后就跳转到start_kernel()中去了。start_kernel()是&#8221;init/main.c&#8221;中的定义的函数，start_kernel()中调用了一系列初始化函数，以完成kernel本身的设置。start_kernel()函数中，做了大量的工作来建立基本的Linux核心环境。如果顺利执行完start_kernel()，则基本的Linux核心环境已经建立起来了。</p>
<p>在start_kernel()的最后，通过调用init()函数，系统创建第一个核心线程，启动了init过程。而核心线程init()主要是来进行一些外设初始化的工作的，包括调用do_basic_setup()完成外设及其驱动程序的加载和初始化。并完成文件系统初始化和root文件系统的安装。</p>
<p>当do_basic_setup()函数返回init()，init()又打开了/dev/console设备，重定向三个标准的输入输出文件stdin、stdout和stderr到控制台，最后，搜索文件系统中的init程序（或者由init=命令行参数指定的程序），并使用 execve()系统调用加载执行init程序。到此init()函数结束，内核的引导部分也到此结束了.</p>
<p><span id="more-391"></span></p>
<p>第二部分：运行init<br />
init的进程号是1，从这一点就能看出，init进程是系统所有进程的起点，Linux在完成核内引导以后，就开始运行init程序，。init程序需要读取配置文件/etc/inittab。inittab是一个不可执行的文本文件，它有若干行指令所组成。在Redhat系统中，inittab的内容如下所示(以“###&#8221;开始的中注释为笔者增加的)：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p391code11'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39111"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
</pre></td><td class="code" id="p391code11"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># inittab       This file describes how the INIT process should set up</span>
<span style="color: #666666; font-style: italic;">#               the system in a certain run-level.</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Author:       Miquel van Smoorenburg,</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#               Modified for RHS Linux by Marc Ewing and Donnie Barnes</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Default runlevel. The runlevels used by RHS are:</span>
<span style="color: #666666; font-style: italic;">#   0 - halt (Do NOT set initdefault to this)</span>
<span style="color: #666666; font-style: italic;">#   1 - Single user mode</span>
<span style="color: #666666; font-style: italic;">#   2 - Multiuser, without NFS (The same as 3, if you do not havenetworking)</span>
<span style="color: #666666; font-style: italic;">#   3 - Full multiuser mode</span>
<span style="color: #666666; font-style: italic;">#   4 - unused</span>
<span style="color: #666666; font-style: italic;">#   5 - X11</span>
<span style="color: #666666; font-style: italic;">#   6 - reboot (Do NOT set initdefault to this)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">###表示当前缺省运行级别为5(initdefault)；</span>
<span style="color: #c20cb9; font-weight: bold;">id</span>:<span style="color: #000000;">5</span>:initdefault:
&nbsp;
<span style="color: #666666; font-style: italic;">###启动时自动执行/etc/rc.d/rc.sysinit脚本(sysinit)</span>
<span style="color: #666666; font-style: italic;"># System initialization.</span>
si::sysinit:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc.sysinit
&nbsp;
l0:<span style="color: #000000;">0</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">0</span>
l1:<span style="color: #000000;">1</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">1</span>
l2:<span style="color: #000000;">2</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">2</span>
l3:<span style="color: #000000;">3</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">3</span>
l4:<span style="color: #000000;">4</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">4</span>
<span style="color: #666666; font-style: italic;">###当运行级别为5时，以5为参数运行/etc/rc.d/rc脚本，init将等待其返回(wait)</span>
l5:<span style="color: #000000;">5</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">5</span>
l6:<span style="color: #000000;">6</span>:<span style="color: #7a0874; font-weight: bold;">wait</span>:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>rc <span style="color: #000000;">6</span>
&nbsp;
<span style="color: #666666; font-style: italic;">###在启动过程中允许按CTRL-ALT-DELETE重启系统</span>
<span style="color: #666666; font-style: italic;"># Trap CTRL-ALT-DELETE</span>
ca::ctrlaltdel:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>shutdown <span style="color: #660033;">-t3</span> <span style="color: #660033;">-r</span> now
&nbsp;
<span style="color: #666666; font-style: italic;"># When our UPS tells us power has failed, assume we have a few minutes</span>
<span style="color: #666666; font-style: italic;"># of power left.  Schedule a shutdown for 2 minutes from now.</span>
<span style="color: #666666; font-style: italic;"># This does, of course, assume you have powerd installed and your</span>
<span style="color: #666666; font-style: italic;"># UPS connected and working correctly.</span>
pf::powerfail:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>shutdown <span style="color: #660033;">-f</span> <span style="color: #660033;">-h</span> +<span style="color: #000000;">2</span> <span style="color: #ff0000;">&quot;Power Failure; System Shutting Down&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># If power was restored before the shutdown kicked in, cancel it.</span>
<span style="color: #c20cb9; font-weight: bold;">pr</span>:<span style="color: #000000;">12345</span>:powerokwait:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>shutdown <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Power Restored; Shutdown Cancelled&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">###在2、3、4、5级别上以ttyX为参数执行/sbin/mingetty程序，打开ttyX终端用于用户登录，</span>
<span style="color: #666666; font-style: italic;">###如果进程退出则再次运行mingetty程序(respawn)</span>
<span style="color: #666666; font-style: italic;"># Run gettys in standard runlevels</span>
<span style="color: #000000;">1</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty1
<span style="color: #000000;">2</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty2
<span style="color: #000000;">3</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty3
<span style="color: #000000;">4</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty4
<span style="color: #000000;">5</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty5
<span style="color: #000000;">6</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty6
&nbsp;
<span style="color: #666666; font-style: italic;">###在5级别上运行xdm程序，提供xdm图形方式登录界面，并在退出时重新执行(respawn)</span>
<span style="color: #666666; font-style: italic;"># Run xdm in runlevel 5</span>
x:<span style="color: #000000;">5</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>prefdm <span style="color: #660033;">-nodaemon</span></pre></td></tr></table></div>

<p>以上面的inittab文件为例，来说明一下inittab的格式。其中以#开始的行是注释行，除了注释行之外，每一行都有以下格式：<br />
id:runlevel:action:process</p>
<p>对上面各项的详细解释如下：</p>
<p>1. id</p>
<p>id是指入口标识符，它是一个字符串，对于getty或mingetty等其他login程序项，要求id与tty的编号相同，否则getty程序将不能正常工作。</p>
<p>2. runlevel</p>
<p>runlevel是init所处于的运行级别的标识，一般使用0－6以及S或s。0、1、6运行级别被系统保留：其中0作为shutdown动作，1作为重启至单用户模式，6为重启；S和s意义相同，表示单用户模式，且无需inittab文件，因此也不在inittab中出现，实际上，进入单用户模式时，init直接在控制台（/dev/console）上运行/sbin/sulogin。在一般的系统实现中，都使用了2、3、4、5几个级别，在Redhat系统中，2表示无NFS支持的多用户模式，3表示完全多用户模式（也是最常用的级别），4保留给用户自定义，5表示XDM图形登录方式。7－9级别也是可以使用的，传统的Unix系统没有定义这几个级别。runlevel可以是并列的多个值，以匹配多个运行级别，对大多数action来说，仅当runlevel与当前运行级别匹配成功才会执行。</p>
<p>3. action</p>
<p>action是描述其后的process的运行方式的。action可取的值包括：initdefault、sysinit、boot、bootwait等：</p>
<p>initdefault是一个特殊的action值，用于标识缺省的启动级别；当init由核心激活以后，它将读取inittab中的initdefault项，取得其中的runlevel，并作为当前的运行级别。如果没有inittab文件，或者其中没有initdefault项，init将在控制台上请求输入runlevel。</p>
<p>sysinit、boot、bootwait等action将在系统启动时无条件运行，而忽略其中的runlevel。</p>
<p>其余的action（不含initdefault）都与某个runlevel相关。各个action的定义在inittab的man手册中有详细的描述。</p>
<p>4. process</p>
<p>process为具体的执行程序。程序后面可以带参数。</p>
<p>第三部分：系统初始化</p>
<p>在init的配置文件中有这么一行：</p>
<p>si::sysinit:/etc/rc.d/rc.sysinit</p>
<p>它调用执行了/etc/rc.d/rc.sysinit，而rc.sysinit是一个bash shell的脚本，它主要是完成一些系统初始化的工作，rc.sysinit是每一个运行级别都要首先运行的重要脚本。它主要完成的工作有：激活交换分区，检查磁盘，加载硬件模块以及其它一些需要优先执行任务。</p>
<p>rc.sysinit约有850多行，但是每个单一的功能还是比较简单，而且带有注释，建议有兴趣的用户可以自行阅读自己机器上的该文件，以了解系统初始化所详细情况。由于此文件较长，所以不在本文中列出来，也不做具体的介绍。</p>
<p>当rc.sysinit程序执行完毕后，将返回init继续下一步。<br />
第四部分：启动对应运行级别的守护进程<br />
在rc.sysinit执行后，将返回init继续其它的动作，通常接下来会执行到/etc/rc.d/rc程序。以运行级别3为例，init将执行配置文件inittab中的以下这行：</p>
<p>l5:5:wait:/etc/rc.d/rc 5</p>
<p>这一行表示以5为参数运行/etc/rc.d/rc，/etc/rc.d/rc是一个Shell脚本，它接受5作为参数，去执行/etc/rc.d/rc5.d/目录下的所有的rc启动脚本，/etc/rc.d/rc5.d/目录中的这些启动脚本实际上都是一些链接文件，而不是真正的rc启动脚本，真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。而这些rc启动脚本有着类似的用法，它们一般能接受start、stop、restart、status等参数。</p>
<p>/etc/rc.d/rc5.d/中的rc启动脚本通常是K或S开头的链接文件，对于以以S开头的启动脚本，将以start参数来运行。而如果发现存在相应的脚本也存在K打头的链接，而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志)，则将首先以stop为参数停止这些已经启动了的守护进程，然后再重新运行。这样做是为了保证是当init改变运行级别时，所有相关的守护进程都将重启。</p>
<p>至于在每个运行级中将运行哪些守护进程，用户可以通过chkconfig或setup中的&#8221;System Services&#8221;来自行设定。常见的守护进程有：</p>
<p>amd：自动安装NFS守护进程<br />
apmd:高级电源管理守护进程<br />
arpwatch：记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对数据库<br />
autofs：自动安装管理进程automount，与NFS相关，依赖于NIS<br />
crond：Linux下的计划任务的守护进程<br />
named：DNS服务器<br />
netfs：安装NFS、Samba和NetWare网络文件系统<br />
network：激活已配置网络接口的脚本程序<br />
nfs：打开NFS服务<br />
portmap：RPC portmap管理器，它管理基于RPC服务的连接<br />
sendmail：邮件服务器sendmail<br />
smb：Samba文件共享/打印服务<br />
syslog：一个让系统引导时起动syslog和klogd系统日志守候进程的脚本<br />
xfs：X Window字型服务器，为本地和远程X服务器提供字型集<br />
Xinetd：支持多种网络服务的核心守护进程，可以管理wuftp、sshd、telnet等服务</p>
<p>这些守护进程也启动完成了，rc程序也就执行完了，然后又将返回init继续下一步。</p>
<p>第五部分：建立终端<br />
rc执行完毕后，返回init。这时基本系统环境已经设置好了，各种守护进程也已经启动了。init接下来会打开6个终端，以便用户登录系统。通过按Alt+Fn(n对应1-6)可以在这6个终端中切换。在inittab中的以下6行就是定义了6个终端：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p391code12'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39112"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p391code12"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">1</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty1
<span style="color: #000000;">2</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty2
<span style="color: #000000;">3</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty3
<span style="color: #000000;">4</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty4
<span style="color: #000000;">5</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty5
<span style="color: #000000;">6</span>:<span style="color: #000000;">2345</span>:respawn:<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>mingetty tty6</pre></td></tr></table></div>

<p>从上面可以看出在2、3、4、5的运行级别中都将以respawn方式运行mingetty程序，mingetty程序能打开终端、设置模式。同时它会显示一个文本登录界面，这个界面就是我们经常看到的登录界面，在这个登录界面中会提示用户输入用户名，而用户输入的用户将作为参数传给login程序来验证用户的身份。</p>
<p>第六部分：登录系统，启动完成</p>
<p>对于运行级别为5的图形方式用户来说，他们的登录是通过一个图形化的登录界面。登录成功后可以直接进入KDE、Gnome等窗口管理器。而本文主要讲的还是文本方式登录的情况：</p>
<p>当我们看到mingetty的登录界面时，我们就可以输入用户名和密码来登录系统了。</p>
<p>Linux的账号验证程序是login，login会接收mingetty传来的用户名作为用户名参数。然后login会对用户名进行分析：如果用户名不是root，且存在/etc/nologin文件，login将输出nologin文件的内容，然后退出。这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许root用户登录，如果不存在这个文件，则root可以在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制，如果不存在这个文件，则没有其他限制。</p>
<p>在分析完用户名后，login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其它信息，比如：主目录是什么、使用何种shell。如果没有指定主目录，将默认为根目录；如果没有指定shell，将默认为/bin/bash。</p>
<p>login程序成功后，会向对应的终端在输出最近一次登录的信息(在/var/log/lastlog中有记录)，并检查用户是否有新邮件(在/usr/spool/mail/的对应用户名目录下)。然后开始设置各种环境变量：对于bash来说，系统首先寻找/etc/profile脚本文件，并执行它；然后如果用户的主目录中存在.bash_profile文件，就执行它，在这些文件中又可能调用了其它配置文件，所有的配置文件执行后后，各种环境变量也设好了，这时会出现大家熟悉的命令行提示符，到此整个启动过程就结束了。</p>
<p>希望通过上面对Linux启动过程的剖析能帮助那些想深入学习Linux用户建立一个相关Linux启动过程的清晰概念，进而可以进一步研究Linux接下来是如何工作的。</p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/391/%e6%8a%80%e6%9c%af/%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f%e4%bd%bf%e7%94%a8/%e5%89%96%e6%9e%90linux%e7%b3%bb%e7%bb%9f%e5%90%af%e5%8a%a8%e8%bf%87%e7%a8%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gcc扩展，在Linux Kernel中的使用示例</title>
		<link>http://zhuwenhao.com/387/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/gcc%e6%89%a9%e5%b1%95%ef%bc%8c%e5%9c%a8linux-kernel%e4%b8%ad%e7%9a%84%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b/</link>
		<comments>http://zhuwenhao.com/387/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/gcc%e6%89%a9%e5%b1%95%ef%bc%8c%e5%9c%a8linux-kernel%e4%b8%ad%e7%9a%84%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b/#comments</comments>
		<pubDate>Thu, 13 May 2010 07:10:34 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[C 语言]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=387</guid>
		<description><![CDATA[GNC CC 是一个功能非常强大的跨平台 C 编译器，它对 C 语言提供了很多扩展，这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。本文把支持 GNU 扩展的 C 语言称为 GNU C。 Linux 内核代码使用了大量的 GNU C 扩展，以至于能够编译 Linux 内核的唯一编译器是 GNU CC，以前甚至出现过编译 Linux 内核要使用特殊的 GNU CC 版本的情
况。本文是对 Linux 内核使用的 GNU C 扩展的一个汇总，希望当你读内核源码遇到不理解的语法和语义时，能从本文找到一个初步的解答，更详细的信息可以查看gcc.info。文中的例子取自 Linux 2.4.18。
语句表达式
==========
GNU C 把包含在括号中的复合语句看做是一个表达式，称为语句表达式，它可以出现在任何允许表达式的地方，你可以在语句表达式中使用循环、局部变量等，原本只能在复合语句中使用。例如：

View Code C1
2
3
4
5
++++ include/linux/kernel.h
159: #define min_t(type,x,y) \
160: ({ type __x = (x); type __y = (y); __x &#38;lt; __y ? ]]></description>
			<content:encoded><![CDATA[<p>GNC CC 是一个功能非常强大的跨平台 C 编译器，它对 C 语言提供了很多扩展，这些扩展对优化、目标代码布局、更安全的检查等方面提供了很强的支持。本文把支持 GNU 扩展的 C 语言称为 GNU C。 Linux 内核代码使用了大量的 GNU C 扩展，以至于能够编译 Linux 内核的唯一编译器是 GNU CC，以前甚至出现过编译 Linux 内核要使用特殊的 GNU CC 版本的情<br />
况。本文是对 Linux 内核使用的 GNU C 扩展的一个汇总，希望当你读内核源码遇到不理解的语法和语义时，能从本文找到一个初步的解答，更详细的信息可以查看gcc.info。文中的例子取自 Linux 2.4.18。</p>
<p>语句表达式<br />
==========<br />
GNU C 把包含在括号中的复合语句看做是一个表达式，称为语句表达式，它可以出现在任何允许表达式的地方，你可以在语句表达式中使用循环、局部变量等，原本只能在复合语句中使用。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code33'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38733"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p387code33"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>kernel.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">159</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define min_t(type,x,y) \
160: ({ type __x = (x); type __y = (y); __x &amp;lt; __y ? __x: __y; })</span>
<span style="color: #339933;">++++</span> net<span style="color: #339933;">/</span>ipv4<span style="color: #339933;">/</span>tcp_output.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">654</span><span style="color: #339933;">:</span> <span style="color: #993333;">int</span> full_space <span style="color: #339933;">=</span> min_t<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">,</span> tp<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>window_clamp<span style="color: #339933;">,</span> tcp_full_space<span style="color: #009900;">&#40;</span>sk<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>复合语句的最后一个语句应该是一个表达式，它的值将成为这个语句表达式的值。这里定义了一个安全的求最小值的宏，在标准 C 中，通常定义为:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code34'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38734"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code34"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define min(x,y) ((x) &amp;lt; (y) ? (x) : (y))</span></pre></td></tr></table></div>

<p>这个定义计算 x 和 y 分别两次，当参数有副作用时，将产生不正确的结果，使用语句表达式只计算参数一次，避免了可能的错误。语句表达式通常用于宏定义。</p>
<p>Typeof<br />
======<br />
使用前一节定义的宏需要知道参数的类型，利用 typeof 可以定义更通用的宏，不必事先知道参数的类型，例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code35'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38735"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p387code35"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>kernel.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">141</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define min(x,y) ({ \
142: const typeof(x) _x = (x); \
143: const typeof(y) _y = (y); \
144: (void) (&amp;amp;_x == &amp;amp;_y); \
145: _x &amp;lt; _y ? _x : _y; })</span></pre></td></tr></table></div>

<p>这里 typeof(x) 表示 x 的值类型，第 142 行定义了一个与 x 类型相同的局部变量 _x 并初使化为 x，注意第 144 行的作用是检查参数 x 和 y 的类型是否相同。typeof 可以用在任何类型可以使用的地方，通常用于宏定义。<br />
零长度数组<br />
======<br />
GNU C 允许使用零长度数组，在定义变长对象的头结构时，这个特性非常有用。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code36'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38736"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p387code36"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>minix_fs.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">85</span><span style="color: #339933;">:</span> <span style="color: #993333;">struct</span> minix_dir_entry <span style="color: #009900;">&#123;</span>
<span style="color: #0000dd;">86</span><span style="color: #339933;">:</span> __u16 inode<span style="color: #339933;">;</span>
<span style="color: #0000dd;">87</span><span style="color: #339933;">:</span> <span style="color: #993333;">char</span> name<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">88</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>结构的最后一个元素定义为零长度数组，它不占结构的空间。在标准 C 中则需要定义数组长度为 1，分配时计算对象大小比较复杂。<br />
可变参数宏<br />
==========<br />
在 GNU C 中，宏可以接受可变数目的参数，就象函数一样，例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code37'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38737"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p387code37"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>kernel.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">110</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define pr_debug(fmt,arg...) \
111: printk(KERN_DEBUG fmt,##arg)</span></pre></td></tr></table></div>

<p>这里 arg 表示其余的参数，可以是零个或多个，这些参数以及参数之间的逗号构成 arg 的值，在宏扩展时替换 arg，例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code38'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38738"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code38"><pre class="c" style="font-family:monospace;">pr_debug<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s:%d&quot;</span><span style="color: #339933;">,</span>filename<span style="color: #339933;">,</span>line<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>扩展为</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code39'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38739"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code39"><pre class="c" style="font-family:monospace;">printk<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;&lt;7&gt;&quot;</span>  <span style="color: #ff0000;">&quot;%s:%d&quot;</span><span style="color: #339933;">,</span> filename<span style="color: #339933;">,</span> line<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>使用 ## 的原因是处理 arg 不匹配任何参数的情况，这时 arg 的值为空，GNU C 预处理器在这种特殊情况下，丢弃 ## 之前的逗号，这样</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code40'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38740"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code40"><pre class="c" style="font-family:monospace;">pr_debug<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;success!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>扩展为</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code41'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38741"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code41"><pre class="c" style="font-family:monospace;">printk<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;&lt;7&gt;&quot;</span>  <span style="color: #ff0000;">&quot;success!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>注意最后没有逗号。<br />
标号元素<br />
========<br />
标准 C 要求数组或结构变量的初使化值必须以固定的顺序出现，在 GNU C 中，通过指定索引或结构域名，允许初始化值以任意顺序出现。指定数组索引的方法是在初始化值前写 &#8216;[INDEX] =&#8217;，要指定一个范围使用[FIRST ... LAST] =&#8217; 的形式，<br />
例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code42'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38742"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p387code42"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">+++++</span> arch<span style="color: #339933;">/</span>i386<span style="color: #339933;">/</span>kernel<span style="color: #339933;">/</span>irq.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">1079</span><span style="color: #339933;">:</span> <span style="color: #993333;">static</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> irq_affinity <span style="color: #009900;">&#91;</span>NR_IRQS<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span> ... <span style="color: #202020;">NR_IRQS</span><span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> ~0UL <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>将数组的所有元素初使化为 ~0UL，这可以看做是一种简写形式。<br />
要指定结构元素，在元素值前写 &#8216;FIELDNAME:&#8217;，例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code43'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38743"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p387code43"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> fs<span style="color: #339933;">/</span>ext2<span style="color: #339933;">/</span>file.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">41</span><span style="color: #339933;">:</span> <span style="color: #993333;">struct</span> file_operations ext2_file_operations <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
<span style="color: #0000dd;">42</span><span style="color: #339933;">:</span> llseek<span style="color: #339933;">:</span> generic_file_llseek<span style="color: #339933;">,</span>
<span style="color: #0000dd;">43</span><span style="color: #339933;">:</span> read<span style="color: #339933;">:</span> generic_file_read<span style="color: #339933;">,</span>
<span style="color: #0000dd;">44</span><span style="color: #339933;">:</span> write<span style="color: #339933;">:</span> generic_file_write<span style="color: #339933;">,</span>
<span style="color: #0000dd;">45</span><span style="color: #339933;">:</span> ioctl<span style="color: #339933;">:</span> ext2_ioctl<span style="color: #339933;">,</span>
<span style="color: #0000dd;">46</span><span style="color: #339933;">:</span> mmap<span style="color: #339933;">:</span> generic_file_mmap<span style="color: #339933;">,</span>
<span style="color: #0000dd;">47</span><span style="color: #339933;">:</span> open<span style="color: #339933;">:</span> generic_file_open<span style="color: #339933;">,</span>
<span style="color: #0000dd;">48</span><span style="color: #339933;">:</span> release<span style="color: #339933;">:</span> ext2_release_file<span style="color: #339933;">,</span>
<span style="color: #0000dd;">49</span><span style="color: #339933;">:</span> fsync<span style="color: #339933;">:</span> ext2_sync_file<span style="color: #339933;">,</span>
<span style="color: #0000dd;">50</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>将结构 ext2_file_operations 的元素 llseek 初始化为 generic_file_llseek，元素 read 初始化为 genenric_file_read，依次类推。我觉得这是 GNU C 扩展中最好的特性之一，当结构的定义变化以至元素的偏移改变时，这种初始化方法仍然保证已知元素的正确性。对于未出现在初始化中的元素，其初值为 0。<br />
Case 范围<br />
=========<br />
GNU C 允许在一个 case 标号中指定一个连续范围的值，例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code44'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38744"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p387code44"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> arch<span style="color: #339933;">/</span>i386<span style="color: #339933;">/</span>kernel<span style="color: #339933;">/</span>irq.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">1062</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'0'</span> ... <span style="color: #ff0000;">'9'</span><span style="color: #339933;">:</span> c <span style="color: #339933;">-=</span> <span style="color: #ff0000;">'0'</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">1063</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'a'</span> ... <span style="color: #ff0000;">'f'</span><span style="color: #339933;">:</span> c <span style="color: #339933;">-=</span> <span style="color: #ff0000;">'a'</span><span style="color: #339933;">-</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">1064</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'A'</span> ... <span style="color: #ff0000;">'F'</span><span style="color: #339933;">:</span> c <span style="color: #339933;">-=</span> <span style="color: #ff0000;">'A'</span><span style="color: #339933;">-</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'0'</span> ... <span style="color: #ff0000;">'9'</span><span style="color: #339933;">:</span></pre></td></tr></table></div>

<p>相当于</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code45'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38745"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p387code45"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'0'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'1'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'2'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'3'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'4'</span><span style="color: #339933;">:</span>
<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'5'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'6'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'7'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'8'</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'9'</span><span style="color: #339933;">:</span></pre></td></tr></table></div>

<p>声明的特殊属性<br />
==============<br />
GNU C 允许声明函数、变量和类型的特殊属性，以便手工的代码优化和更仔细的代码检查。要指定一个声明的属性，在声明后写</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code46'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38746"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p387code46"><pre class="c" style="font-family:monospace;">__attribute__ <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span> ATTRIBUTE <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>其中 ATTRIBUTE 是属性说明，多个属性以逗号分隔。GNU C 支持十几个属性，这里介绍最常用的：<br />
* noreturn<br />
属性 noreturn 用于函数，表示该函数从不返回。这可以让编译器生成稍微优化的代码，最重要的是可以消除不必要的警告信息比如未初使化的变量。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code47'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38747"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p387code47"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>kernel.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">47</span><span style="color: #339933;">:</span> <span style="color: #339933;"># define ATTRIB_NORET __attribute__((noreturn)) ....</span>
<span style="color: #0000dd;">61</span><span style="color: #339933;">:</span> asmlinkage NORET_TYPE <span style="color: #993333;">void</span> do_exit<span style="color: #009900;">&#40;</span><span style="color: #993333;">long</span> error_code<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>ATTRIB_NORET;<br />
* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)<br />
属性 format 用于函数，表示该函数使用 printf, scanf 或 strftime 风格的参数，使用这类函数最容易犯的错误是格式串与参数不匹配，指定 format 属性可以让编译器根据格式串检查参数类型。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code48'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38748"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p387code48"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>kernel.<span style="color: #202020;">h</span><span style="color: #339933;">?</span>
<span style="color: #0000dd;">89</span><span style="color: #339933;">:</span> asmlinkage <span style="color: #993333;">int</span> printk<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> fmt<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span>
<span style="color: #0000dd;">90</span><span style="color: #339933;">:</span> __attribute__ <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>format <span style="color: #009900;">&#40;</span><a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>表示第一个参数是格式串，从第二个参数起根据格式串检查参数。<br />
* unused<br />
属性 unused 用于函数和变量，表示该函数或变量可能不使用，这个属性可以避免编译器产生警告信息。<br />
* section (&#8220;section-name&#8221;)<br />
属性 section 用于函数和变量，通常编译器将函数放在 .text 节，变量放在.data 或 .bss 节，使用 section 属性，可以让编译器将函数或变量放在指定的节中。</p>
<p>GNU CC 预定义了两个标志符保存当前函数的名字，__FUNCTION__ 保存函数在源码中的名字，__PRETTY_FUNCTION__ 保存带语言特色的名字。在 C 函数中，这两个名字是相同的，在 C++ 函数中，__PRETTY_FUNCTION__ 包括函数返回类型等额外信息，Linux 内核只使用了 __FUNCTION__。</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code49'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38749"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p387code49"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> fs<span style="color: #339933;">/</span>ext2<span style="color: #339933;">/</span>super.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">98</span><span style="color: #339933;">:</span> <span style="color: #993333;">void</span> ext2_update_dynamic_rev<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> super_block <span style="color: #339933;">*</span>sb<span style="color: #009900;">&#41;</span>
<span style="color: #0000dd;">99</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
<span style="color: #0000dd;">100</span><span style="color: #339933;">:</span> <span style="color: #993333;">struct</span> ext2_super_block <span style="color: #339933;">*</span>es <span style="color: #339933;">=</span> EXT2_SB<span style="color: #009900;">&#40;</span>sb<span style="color: #009900;">&#41;</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>s_es<span style="color: #339933;">;</span>
<span style="color: #0000dd;">101</span><span style="color: #339933;">:</span>
<span style="color: #0000dd;">102</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>le32_to_cpu<span style="color: #009900;">&#40;</span>es<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>s_rev_level<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> EXT2_GOOD_OLD_REV<span style="color: #009900;">&#41;</span>
<span style="color: #0000dd;">103</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">104</span><span style="color: #339933;">:</span>
<span style="color: #0000dd;">105</span><span style="color: #339933;">:</span> ext2_warning<span style="color: #009900;">&#40;</span>sb<span style="color: #339933;">,</span> __FUNCTION__<span style="color: #339933;">,</span>
<span style="color: #0000dd;">106</span><span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;updating to rev %d because of new feature flag, &quot;</span>
<span style="color: #0000dd;">107</span><span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;running e2fsck is recommended&quot;</span><span style="color: #339933;">,</span>
<span style="color: #0000dd;">108</span><span style="color: #339933;">:</span> EXT2_DYNAMIC_REV<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>这里 __FUNCTION__ 将被替换为字符串 &#8220;ext2_update_dynamic_rev&#8221;。虽然__FUNCTION__ 看起来类似于标准 C 中的 __FILE__，但实际上 __FUNCTION__是被编译器替换的，不象 __FILE__ 被预处理器替换。<br />
内建函数<br />
========<br />
GNU C 提供了大量的内建函数，其中很多是标准 C 库函数的内建版本，例如memcpy，它们与对应的 C 库函数功能相同，本文不讨论这类函数，其他内建函数的名字通常以 __builtin 开始。<br />
* __builtin_return_address (LEVEL)<br />
内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址，参数LEVEL 指定在栈上搜索框架的个数，0 表示当前函数的返回地址，1 表示当前函数的调用者的返回地址，依此类推。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code50'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38750"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p387code50"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> kernel<span style="color: #339933;">/</span>sched.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">437</span><span style="color: #339933;">:</span> printk<span style="color: #009900;">&#40;</span>KERN_ERR <span style="color: #ff0000;">&quot;schedule_timeout: wrong timeout &quot;</span>
<span style="color: #0000dd;">438</span><span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;value %lx from %p<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> timeout<span style="color: #339933;">,</span>
<span style="color: #0000dd;">439</span><span style="color: #339933;">:</span> __builtin_return_address<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>* __builtin_constant_p(EXP)<br />
内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数，如果参数EXP 的值是常数，函数返回 1，否则返回 0。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code51'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38751"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p387code51"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>asm<span style="color: #339933;">-</span>i386<span style="color: #339933;">/</span>bitops.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">249</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define test_bit(nr,addr) \
250: (__builtin_constant_p(nr) ? \
251: constant_test_bit((nr),(addr)) : \
252: variable_test_bit((nr),(addr)))</span></pre></td></tr></table></div>

<p>很多计算或操作在参数为常数时有更优化的实现，在 GNU C 中用上面的方法可以根据参数是否为常数，只编译常数版本或非常数版本，这样既不失通用性，又能在参数是常数时编译出最优化的代码。<br />
* __builtin_expect(EXP, C)<br />
内建函数 __builtin_expect 用于为编译器提供分支预测信息，其返回值是整数表达式 EXP 的值，C 的值必须是编译时常数。例如：</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p387code52'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38752"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p387code52"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">++++</span> include<span style="color: #339933;">/</span>linux<span style="color: #339933;">/</span>compiler.<span style="color: #202020;">h</span>
<span style="color: #0000dd;">13</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define likely(x) __builtin_expect((x),1)</span>
<span style="color: #0000dd;">14</span><span style="color: #339933;">:</span> <span style="color: #339933;">#define unlikely(x) __builtin_expect((x),0)</span>
<span style="color: #339933;">++++</span> kernel<span style="color: #339933;">/</span>sched.<span style="color: #202020;">c</span>
<span style="color: #0000dd;">564</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>unlikely<span style="color: #009900;">&#40;</span>in_interrupt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #0000dd;">565</span><span style="color: #339933;">:</span> printk<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Scheduling in interrupt<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">566</span><span style="color: #339933;">:</span> BUG<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000dd;">567</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>这个内建函数的语义是 EXP 的预期值是 C，编译器可以根据这个信息适当地重排语句块的顺序，使程序在预期的情况下有更高的执行效率。上面的例子表示处于中断上下文是很少发生的，第 565-566 行的目标码可能会放在较远的位置，以保证经常执行的目标码更紧凑。 ﻿</p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/387/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/gcc%e6%89%a9%e5%b1%95%ef%bc%8c%e5%9c%a8linux-kernel%e4%b8%ad%e7%9a%84%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>自动备份数据库并发送到电子邮箱的脚本</title>
		<link>http://zhuwenhao.com/385/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e8%87%aa%e5%8a%a8%e5%a4%87%e4%bb%bd%e6%95%b0%e6%8d%ae%e5%ba%93%e5%b9%b6%e5%8f%91%e9%80%81%e5%88%b0%e7%94%b5%e5%ad%90%e9%82%ae%e7%ae%b1%e7%9a%84%e8%84%9a%e6%9c%ac/</link>
		<comments>http://zhuwenhao.com/385/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e8%87%aa%e5%8a%a8%e5%a4%87%e4%bb%bd%e6%95%b0%e6%8d%ae%e5%ba%93%e5%b9%b6%e5%8f%91%e9%80%81%e5%88%b0%e7%94%b5%e5%ad%90%e9%82%ae%e7%ae%b1%e7%9a%84%e8%84%9a%e6%9c%ac/#comments</comments>
		<pubDate>Tue, 11 May 2010 12:17:43 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[服务器和网站类]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=385</guid>
		<description><![CDATA[将网站数据库备份后留在本地硬盘上，并不是一个可靠的方案。我就把压缩后的文件发送到电子邮件信箱里。Gmail的附件目前最大25兆，QQ邮箱是50兆，所以本方法不适合大型商业网站，个人独立博客比较合适的说。
下面贴出脚本，本方法需要先安装mutt邮件客户端。
请注意，有些老点的文章中给出的示例，在邮件地址前面没有 &#8212; 符号，这会造成新版本的mutt提示 No recipients specified. 只要加上 &#8212; 符号就可以了。
还有一个注意的地方，如果连续发送很多数据库文件并保存在Sent文件中，很快就会消耗大量的本地硬盘空间。让mutt默认不保存已发送邮件的方法是修改 /etc/Muttrc文件，或者在当前用户home目录下，修改或建立一个隐藏文件 .muttrc (注意这两个M的大小写)， 修改或增加这样一行 set record=&#8221;/dev/null&#8221; （一般默认为 set record=&#8221;~/Sent&#8221;），就可以让Mutt不保存已发送邮件从而节省空间了。

View Code BASH1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/sh
sendfiletogmail &#40;&#41;
&#123;
        FilePath=$1
        FileName=$2&#34;.bz2&#34;
        mutt -s &#34;Database Backup File ${FileName}&#34; -a${FilePath}&#34;/&#34;${FileName} -- yourMailBox@gmail.com &#60; &#34;/path/to/emailbody.txt&#34;
&#125;
&#160;
&#160;
backup ]]></description>
			<content:encoded><![CDATA[<p>将网站数据库备份后留在本地硬盘上，并不是一个可靠的方案。我就把压缩后的文件发送到电子邮件信箱里。Gmail的附件目前最大25兆，QQ邮箱是50兆，所以本方法不适合大型商业网站，个人独立博客比较合适的说。</p>
<p>下面贴出脚本，本方法需要先安装mutt邮件客户端。<br />
请注意，有些老点的文章中给出的示例，在邮件地址前面没有 &#8212; 符号，这会造成新版本的mutt提示 No recipients specified. 只要加上 &#8212; 符号就可以了。<br />
还有一个注意的地方，如果连续发送很多数据库文件并保存在Sent文件中，很快就会消耗大量的本地硬盘空间。让mutt默认不保存已发送邮件的方法是修改 /etc/Muttrc文件，或者在当前用户home目录下，修改或建立一个隐藏文件 .muttrc (注意这两个M的大小写)， 修改或增加这样一行 set record=&#8221;/dev/null&#8221; （一般默认为 set record=&#8221;~/Sent&#8221;），就可以让Mutt不保存已发送邮件从而节省空间了。</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p385code54'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p38554"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code" id="p385code54"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
sendfiletogmail <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
        <span style="color: #007800;">FilePath</span>=<span style="color: #007800;">$1</span>
        <span style="color: #007800;">FileName</span>=<span style="color: #007800;">$2</span><span style="color: #ff0000;">&quot;.bz2&quot;</span>
        mutt <span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;Database Backup File <span style="color: #007800;">${FileName}</span>&quot;</span> <span style="color: #660033;">-a</span><span style="color: #800000;">${FilePath}</span><span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #800000;">${FileName}</span> <span style="color: #660033;">--</span> yourMailBox<span style="color: #000000; font-weight: bold;">@</span>gmail.com <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #ff0000;">&quot;/path/to/emailbody.txt&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
backup <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
        <span style="color: #007800;">DBName</span>=$<span style="color: #000000; font-weight: bold;">@</span>
        <span style="color: #007800;">BackupPath</span>=<span style="color: #ff0000;">&quot;/path/to/&quot;</span><span style="color: #800000;">${DBName}</span>
        <span style="color: #007800;">BackupName</span>=<span style="color: #800000;">${DBName}</span>-<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #ff0000;">&quot;+[%z%Z]%Y-%m-%d-%H-%M-%S&quot;</span><span style="color: #000000; font-weight: bold;">`</span><span style="color: #ff0000;">&quot;.sql&quot;</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${BackupPath}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #800000;">${BackupPath}</span>;
                <span style="color: #000000; font-weight: bold;">then</span>
                                <span style="color: #000000; font-weight: bold;">if</span>        mysqldump <span style="color: #660033;">-uroot</span> <span style="color: #660033;">-pYourPasswd</span> \
                                                <span style="color: #660033;">--default-character-set</span>=utf8 <span style="color: #660033;">--opt</span> <span style="color: #660033;">--master-data</span>=<span style="color: #000000;">1</span> \
                                                <span style="color: #660033;">--single-transaction</span> <span style="color: #660033;">--flush-logs</span> \
                                                <span style="color: #800000;">${DBName}</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${BackupPath}</span><span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #800000;">${BackupName}</span>;
                                <span style="color: #000000; font-weight: bold;">then</span>
                                                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #800000;">${BackupName}</span><span style="color: #ff0000;">&quot;Backup success!&quot;</span>
                                                <span style="color: #c20cb9; font-weight: bold;">bzip2</span> <span style="color: #660033;">-q</span> <span style="color: #660033;">-s</span>  <span style="color: #800000;">${BackupPath}</span><span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #800000;">${BackupName}</span>;
                                                sendfiletogmail <span style="color: #800000;">${BackupPath}</span> <span style="color: #800000;">${BackupName}</span>
                                <span style="color: #000000; font-weight: bold;">else</span>
                                                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #800000;">${BackupName}</span><span style="color: #ff0000;">&quot;Backup Failed@@@@@@@@@@@@@@@@@@@@@@@@&quot;</span>
                                <span style="color: #000000; font-weight: bold;">fi</span>
                <span style="color: #000000; font-weight: bold;">fi</span>
                <span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #800000;">${BackupPath}</span><span style="color: #ff0000;">&quot;/&quot;</span> <span style="color: #660033;">-ctime</span> +<span style="color: #000000;">7</span> <span style="color: #660033;">-exec</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span> \;
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #666666; font-style: italic;">#Call the function to backup database assigned below</span>
backup  yourDBnamd_db</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/385/%e6%8a%80%e6%9c%af/%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%92%8c%e7%bd%91%e7%ab%99%e7%b1%bb/%e8%87%aa%e5%8a%a8%e5%a4%87%e4%bb%bd%e6%95%b0%e6%8d%ae%e5%ba%93%e5%b9%b6%e5%8f%91%e9%80%81%e5%88%b0%e7%94%b5%e5%ad%90%e9%82%ae%e7%ae%b1%e7%9a%84%e8%84%9a%e6%9c%ac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[建站日记]]></series:name>
	</item>
		<item>
		<title>程序员修炼之路－C语言</title>
		<link>http://zhuwenhao.com/375/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/%e7%a8%8b%e5%ba%8f%e5%91%98%e4%bf%ae%e7%82%bc%e4%b9%8b%e8%b7%af%ef%bc%8dc%e8%af%ad%e8%a8%80/</link>
		<comments>http://zhuwenhao.com/375/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/%e7%a8%8b%e5%ba%8f%e5%91%98%e4%bf%ae%e7%82%bc%e4%b9%8b%e8%b7%af%ef%bc%8dc%e8%af%ad%e8%a8%80/#comments</comments>
		<pubDate>Sun, 09 May 2010 12:50:59 +0000</pubDate>
		<dc:creator>朱文昊 Albert Zhu</dc:creator>
				<category><![CDATA[C 语言]]></category>
		<category><![CDATA[构造]]></category>

		<guid isPermaLink="false">http://zhuwenhao.com/?p=375</guid>
		<description><![CDATA[在程序员修炼之路这个系列里面，转载过几篇他人的文章。最近有同学问我如何深入学习C语言和职业规划的问题，让我决心自己动手总结一些观点，和朋友共勉。于是就有了这篇同名文章。
要想成为一名合格的C语言程序员，读什么样的书是一个首先碰到的基本问题。我的品位是，读计算机方面的著作，一定要读国外人写的经典级别的书。回忆我的往事，在中学时候看了一点BASIC基础，学会了盲打，会用了Windows 3X和95，这些就是我在读大学前全部的计算机基础知识。在大学第一年的寒假，回家的火车上，我没有买到座位票，于是只好站着回家。在这十八个小时的旅途中，我阅读了大约1/2的《C程序设计语言》，对，就是那本Kernighan和Richie合著的薄薄的书。不过惭愧的是，我当时的英语很差，读的当然是东南大学徐宝文翻译的第一版。徐先生的翻译很好，所以我才能顺利读下来。有人可能觉得奇怪，没有什么基础的情况下，如何能读完这么一本书？我的感受是，当要学习一种全新的东西，读书不能奢望全理解，勇敢的看下去，看完它，和作者的第一次沟通才能完成。
这第一次沟通，奠定了我的C语言基础知识，也决定了我今后在C语言程序员、系统软件设计、嵌入式系统设计等方面的职业脉络。读了第一本C语言经典之后，应该就可以编写一些和书中例程差不多的小程序了。接下来需要阅读的经典有：《C专家编程》(Expert C Programming &#8212; Deep C Secrets)、《C陷阱与缺陷》(C Traps and Pitfalls)、《C和指针》(Pointers on C)、《C语言核心技术》(C in a Nutshell)、《代码大全》(Code Complete)。读完了这些书，基本上就可以号称是C语言程序员了。
其中《C和指针》我接触的比较晚，非常的遗憾。当我读了《C和指针》，那种相见恨晚的感觉，难于言表。《C专家编程》《C陷阱与缺陷》这两本书，作者处的时代很久远了。如果在现代PC程序设计领域，相关问题可能很少遇到。但是对C语言程序员而言，还是要继续列为必读书目，因为那些晦涩的问题，还是会不停的重现在嵌入式系统的硬件和编译环境里。《代码大全》结合一定的工作经验来读，会有更深的感触。
学习C语言的路还没有结束，真的要理解C语言，你就要了解“语言”，读一读《程学设计语言》(Programming Language-Michael L. Scott)吧。这本研究生和本科课程通用的教材，会让你对C语言的了解上升一个层次，不，一个数量级。
过了这个界线，C语言的学习就该依据职业规划来细分道路了。我只能根据自己的经验谈谈。
首先，学会用Linux操作体系或者其他类似的＊nix系统，因为这些系统是面向程序员的操作系统，如果你真的是一个程序员，在＊nix你会感到更舒服。会用Gcc也是必须的。
其次，读一下Intel出版的《多核程序设计》。
(本文未完成，请期待更新)
]]></description>
			<content:encoded><![CDATA[<p>在程序员修炼之路这个系列里面，转载过几篇他人的文章。最近有同学问我如何深入学习C语言和职业规划的问题，让我决心自己动手总结一些观点，和朋友共勉。于是就有了这篇同名文章。</p>
<p>要想成为一名合格的C语言程序员，读什么样的书是一个首先碰到的基本问题。我的品位是，读计算机方面的著作，一定要读国外人写的经典级别的书。回忆我的往事，在中学时候看了一点BASIC基础，学会了盲打，会用了Windows 3X和95，这些就是我在读大学前全部的计算机基础知识。在大学第一年的寒假，回家的火车上，我没有买到座位票，于是只好站着回家。在这十八个小时的旅途中，我阅读了大约1/2的《C程序设计语言》，对，就是那本Kernighan和Richie合著的薄薄的书。不过惭愧的是，我当时的英语很差，读的当然是东南大学徐宝文翻译的第一版。徐先生的翻译很好，所以我才能顺利读下来。有人可能觉得奇怪，没有什么基础的情况下，如何能读完这么一本书？我的感受是，当要学习一种全新的东西，读书不能奢望全理解，勇敢的看下去，看完它，和作者的第一次沟通才能完成。</p>
<p>这第一次沟通，奠定了我的C语言基础知识，也决定了我今后在C语言程序员、系统软件设计、嵌入式系统设计等方面的职业脉络。读了第一本C语言经典之后，应该就可以编写一些和书中例程差不多的小程序了。接下来需要阅读的经典有：《C专家编程》(Expert C Programming &#8212; Deep C Secrets)、《C陷阱与缺陷》(C Traps and Pitfalls)、《C和指针》(Pointers on C)、《C语言核心技术》(C in a Nutshell)、《代码大全》(Code Complete)。读完了这些书，基本上就可以号称是C语言程序员了。</p>
<p>其中《C和指针》我接触的比较晚，非常的遗憾。当我读了《C和指针》，那种相见恨晚的感觉，难于言表。《C专家编程》《C陷阱与缺陷》这两本书，作者处的时代很久远了。如果在现代PC程序设计领域，相关问题可能很少遇到。但是对C语言程序员而言，还是要继续列为必读书目，因为那些晦涩的问题，还是会不停的重现在嵌入式系统的硬件和编译环境里。《代码大全》结合一定的工作经验来读，会有更深的感触。</p>
<p>学习C语言的路还没有结束，真的要理解C语言，你就要了解“语言”，读一读《程学设计语言》(Programming Language-Michael L. Scott)吧。这本研究生和本科课程通用的教材，会让你对C语言的了解上升一个层次，不，一个数量级。</p>
<p>过了这个界线，C语言的学习就该依据职业规划来细分道路了。我只能根据自己的经验谈谈。</p>
<p>首先，学会用Linux操作体系或者其他类似的＊nix系统，因为这些系统是面向程序员的操作系统，如果你真的是一个程序员，在＊nix你会感到更舒服。会用Gcc也是必须的。</p>
<p>其次，读一下Intel出版的《多核程序设计》。</p>
<p>(本文未完成，请期待更新)</p>
]]></content:encoded>
			<wfw:commentRss>http://zhuwenhao.com/375/%e6%8a%80%e6%9c%af/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1%e8%af%ad%e8%a8%80/c-%e8%af%ad%e8%a8%80/%e7%a8%8b%e5%ba%8f%e5%91%98%e4%bf%ae%e7%82%bc%e4%b9%8b%e8%b7%af%ef%bc%8dc%e8%af%ad%e8%a8%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[程序员修炼之路]]></series:name>
	</item>
	</channel>
</rss>
