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

<channel>
	<title>Freeland &#124; 逍遥郡</title>
	<atom:link href="http://erera.net/feed" rel="self" type="application/rss+xml" />
	<link>http://erera.net</link>
	<description>公子未名 ™ 且歌且行 ¶ 乘天地之正 御六气之辩 以游于无穷 是为逍遥</description>
	<lastBuildDate>Tue, 05 Jan 2010 09:20:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>单细胞剧情的Avatar</title>
		<link>http://erera.net/blog/avatar-review.html</link>
		<comments>http://erera.net/blog/avatar-review.html#comments</comments>
		<pubDate>Tue, 05 Jan 2010 08:54:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[电影]]></category>
		<category><![CDATA[movie]]></category>

		<guid isPermaLink="false">http://erera.net/?p=386</guid>
		<description><![CDATA[
Avatar是最近势头最劲的电影啦，再加上我对科幻题材的片子都情有独钟，且至今没看过IMAX，所以特别期待。不过在大陆首映的时间不太好，1月4号，刚好错过了元旦假期，不知道是怎么想的。还好天降瑞雪，于是以天气恶劣为由，不用去上班；不过即使是在工作日，电影院依然火爆无比。话说，北京的IMAX影院只有三家，按照屏幕大小分别是：中国电影博物馆、UME华星和石景山的万达。华星的IMAX场次不多，一天才四五场。本来打算直接远程购票了，没想到订票电话一直占线，网络订票被告知无法进行，无奈之下只有早早扒完午饭，跑去人肉买票。真是太不人性化了，是说以此增加付出成本，来区分对Avatar的热情程度？不过一到影院心里拔凉拔凉的，高高的显示屏上打出，白天的四个场次全满，只剩半夜12点的还有些座位；心想总不能白跑一趟，于是弄了张0点的票，就当作假期最后的疯狂吧。
半夜场也是爆满，目测90%以上都是二三十的年轻人，估计大伯大婶们也熬不起夜。观影效果不错，不知道是不是因为座位很靠后了，所以也不觉得27米的IMAX屏特别宽大，至少还没能占满我整个眼球 @@ 第一次戴眼睛看IMAX3D，的确立体效果明显，有种身临其境的感觉；尤其是描绘潘朵拉星球的瑰丽无比的森林景色，美轮美奂的圣树种子，轻灵强健的纳威族人，的确是让人叹为观止，这是一次无比酣畅的视听盛宴，也许从这方面来将，Avatar的确可以算作电影制作上的一次里程碑，我必须给他打满分。
不过Avatar的惊喜也到到此为止了，也许是我的期望过高，单从剧情上来说，Avatar只能算中等偏上的好莱坞商业片水准吧，可能比前段时间的《2012》稍微强点，但是比起《魔戒》、《星球大战》这种同是魔幻或者科幻题材的史诗巨制来说，简直差了不止10条街。就这么说吧，Avatar的情节适合单细胞动物去欣赏，从头到位就一条主线，没有其他暗线或者分支，所有的矛盾冲突就是人族和纳威族的争地斗争。完全比不上《魔戒》、《星球大战》，后者都是数条线索明暗交错，各种各样的人物粉墨登场，各方面的矛盾冲突数次交汇，这种剧情就类似金庸小说《天龙八部》那样，像一个炉子上烧着的水，越来越精彩，越来越沸腾。而Avatar里基本就是一些脸谱样的几个人物，基本看到开头就猜到了结局，只能评价为创新程度一般，让人有些味如嚼蜡。
在Avatar里能联想到其他一些电影和游戏，比如公司的负责人和雇佣兵上校，简直就是《异形》系列的翻版。纳威族人就是暗夜精灵化的虫族，因为他们栖身在一株参天大树上，喜爱森林，倡导人与自然和谐共处。他们非常注重精神的力量，但他们的机械工艺又很烂，还没到神族的水准，和土著人一样，所以差不多就是虫族的样子。而且纳威人也有一个精神的共同体爱娃，就和虫族的主脑一样，联系着所有纳威人的精神纽带。尤其最后主脑，也就是爱娃发威，我看到密密麻麻的虫族部队，包括小狗、飞龙、猛犸（请各自对应潘朵拉星球的生物）向潮水一般一波波冲击着人族部队的时候，俺的心突然激动了，这才是生命的残酷力量呀。突然有些可惜，拍这种残废marine搞定酋长女儿的经典狗血剧情，还不如老老实实以《星际争霸》为蓝本，那拍出的就是一副鸿篇巨制啊；可不比这光靠画面取胜的Avatar强多了？
就这样，为了争夺这颗富含矿产的潘朵拉星球，人类的一个远征军前哨在上校愚蠢的指挥下被纳威族吞灭了，但是人类贪婪的扩展欲望是无法就这样被浇灭的，人类对资源的掠夺是不会轻易停下脚步的。很快，在纳威人还未来得及消化完欢庆的盛宴时，一个整编的人类行星级巡航编队悄然出现在了潘朵拉星球上空，把战争的阴影重新投向了这颗童话般的星球。另一方面，主脑爱娃集千万代精神力量为一身，开始孵化更富有战斗力的纳威族人，以对抗人类的进攻，并且以强大的精神力召唤它的同盟的帮助，新的大战一触即发。这是Avatar下集剧透  
]]></description>
			<content:encoded><![CDATA[<p><img src="http://lh4.ggpht.com/_AogbBxxzmC0/S0L-nh3jF3I/AAAAAAAAJK4/f_fgUjy23CE/s800/avatar_poster_2.jpg" alt="Avatar poster" /></p>
<p><a href="http://www.douban.com/subject/1652587/" class="liexternal">Avatar</a>是最近势头最劲的电影啦，再加上我对科幻题材的片子都情有独钟，且至今没看过IMAX，所以特别期待。不过在大陆首映的时间不太好，1月4号，刚好错过了元旦假期，不知道是怎么想的。还好天降瑞雪，于是以天气恶劣为由，不用去上班；不过即使是在工作日，电影院依然火爆无比。话说，北京的IMAX影院只有三家，按照屏幕大小分别是：中国电影博物馆、UME华星和石景山的万达。华星的IMAX场次不多，一天才四五场。本来打算直接远程购票了，没想到订票电话一直占线，网络订票被告知无法进行，无奈之下只有早早扒完午饭，跑去人肉买票。真是太不人性化了，是说以此增加付出成本，来区分对Avatar的热情程度？不过一到影院心里拔凉拔凉的，高高的显示屏上打出，白天的四个场次全满，只剩半夜12点的还有些座位；心想总不能白跑一趟，于是弄了张0点的票，就当作假期最后的疯狂吧。</p>
<p>半夜场也是爆满，目测90%以上都是二三十的年轻人，估计大伯大婶们也熬不起夜。观影效果不错，不知道是不是因为座位很靠后了，所以也不觉得27米的IMAX屏特别宽大，至少还没能占满我整个眼球 @@ 第一次戴眼睛看IMAX3D，的确立体效果明显，有种身临其境的感觉；尤其是描绘潘朵拉星球的瑰丽无比的森林景色，美轮美奂的圣树种子，轻灵强健的纳威族人，的确是让人叹为观止，这是一次无比酣畅的视听盛宴，也许从这方面来将，Avatar的确可以算作电影制作上的一次里程碑，我必须给他打满分。</p>
<p>不过Avatar的惊喜也到到此为止了，也许是我的期望过高，单从剧情上来说，Avatar只能算中等偏上的好莱坞商业片水准吧，可能比前段时间的《<a href="http://www.douban.com/subject/3005875/" class="liexternal">2012</a>》稍微强点，但是比起《<a href="http://www.douban.com/subject/1291552/" class="liexternal">魔戒</a>》、《<a href="http://www.douban.com/subject/1296528/" class="liexternal">星球大战</a>》这种同是魔幻或者科幻题材的史诗巨制来说，简直差了不止10条街。就这么说吧，Avatar的情节适合单细胞动物去欣赏，从头到位就一条主线，没有其他暗线或者分支，所有的矛盾冲突就是人族和纳威族的争地斗争。完全比不上《魔戒》、《星球大战》，后者都是数条线索明暗交错，各种各样的人物粉墨登场，各方面的矛盾冲突数次交汇，这种剧情就类似金庸小说《<a href="http://www.douban.com/subject/1255625/" class="liexternal">天龙八部</a>》那样，像一个炉子上烧着的水，越来越精彩，越来越沸腾。而Avatar里基本就是一些脸谱样的几个人物，基本看到开头就猜到了结局，只能评价为创新程度一般，让人有些味如嚼蜡。</p>
<p>在Avatar里能联想到其他一些电影和游戏，比如公司的负责人和雇佣兵上校，简直就是《<a href="http://www.douban.com/subject/1300868/" class="liexternal">异形</a>》系列的翻版。纳威族人就是暗夜精灵化的虫族，因为他们栖身在一株参天大树上，喜爱森林，倡导人与自然和谐共处。他们非常注重精神的力量，但他们的机械工艺又很烂，还没到神族的水准，和土著人一样，所以差不多就是虫族的样子。而且纳威人也有一个精神的共同体爱娃，就和虫族的主脑一样，联系着所有纳威人的精神纽带。尤其最后主脑，也就是爱娃发威，我看到密密麻麻的虫族部队，包括小狗、飞龙、猛犸（请各自对应潘朵拉星球的生物）向潮水一般一波波冲击着人族部队的时候，俺的心突然激动了，这才是生命的残酷力量呀。突然有些可惜，拍这种残废marine搞定酋长女儿的经典狗血剧情，还不如老老实实以《星际争霸》为蓝本，那拍出的就是一副鸿篇巨制啊；可不比这光靠画面取胜的Avatar强多了？</p>
<p>就这样，为了争夺这颗富含矿产的潘朵拉星球，人类的一个远征军前哨在上校愚蠢的指挥下被纳威族吞灭了，但是人类贪婪的扩展欲望是无法就这样被浇灭的，人类对资源的掠夺是不会轻易停下脚步的。很快，在纳威人还未来得及消化完欢庆的盛宴时，一个整编的人类行星级巡航编队悄然出现在了潘朵拉星球上空，把战争的阴影重新投向了这颗童话般的星球。另一方面，主脑爱娃集千万代精神力量为一身，开始孵化更富有战斗力的纳威族人，以对抗人类的进攻，并且以强大的精神力召唤它的同盟的帮助，新的大战一触即发。这是Avatar下集剧透 <img src='http://erera.net/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/avatar-review.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>大家一起来推</title>
		<link>http://erera.net/blog/lets-twitter.html</link>
		<comments>http://erera.net/blog/lets-twitter.html#comments</comments>
		<pubDate>Wed, 18 Nov 2009 16:46:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://erera.net/?p=373</guid>
		<description><![CDATA[俺同学说得很经典，twitter被这么一封，更加代表一种文化了。由于twitter的100%的开放性，twitter已经衍生出非常多的有趣应用。twitter的口号也已经从展示大家在做什么，改成了“Share and discover what’s happening right now, anywhere in the world.”，这表明twitter正在超更有意义的方向前进，从大家谈论吃饭睡觉的垃圾信息广播站，变成了一个分享即时信息的巨大平台。
虽然现在twitter在国内被盾了，但是由于它的开发性，很容易构建其他的twitter中转服务器，所以GFW是无法通过封禁域名和IP来堵住twitter的消息广播的，比如访问本域名下二级子域名t，就可以访问twitter。当然，现在也可以通过修改hosts来访问twitter。
你可以使用web、PC客户端或者手机等各种方式来访问twitter。如果你在手机上使用twitter的客户端，那么Direct Message甚至可以完全代替短信了，而且Direct Message是保存在twitter服务器上的，只要有网络的地方你就可以访问。和twitter一起流行的还有URL shortening和图片存储服务，目前我觉得比较好用的是http://is.gd和http://yforg.com。一般的客户端可以自定义这两个服务器，以及twitter的中转服务器。
twitter的手机客户端多如牛毛，这里我推荐两个iphone上的客户端，一款是Twitterrific，我觉得它比流行的Tweeite优越的地方在于打开的时候会有新消息提醒，但是这款软件是没有push notification的，另外一款是Twitbird，这款软件带push notification，不过有个不幸的消息，我在使用的过程中，发觉只支持未Jailbreak的iphone  
总之，twitter可以超级方便的分享自己的状态，记录身边有意义的事件，配合手机客户端的话还可以即时分享拍摄的图片，更新自己的位置等等；利用@，retweet等功能，可以很方便和朋友联系，在自己的圈子里发布消息公告等等，这点和即将流行的Google Wave也有异曲同工之妙。而且这些功能都是twitter在这两三年的发展中逐渐演化而来的，100% open的twitter还在不断进化中，可以预料它在未来会更加有趣和精彩。而我们唯一所需要做的，就是加入twitter，越多的朋友加入，将有越多的信息分享，越紧密的联系沟通，让我们一起推吧。
我的twitter：https://twitter.com/erera

访问twitter官方站点的办法
把下边的内容加入hosts文件：

168.143.162.36 www.twitter.com
168.143.162.36 twitter.com
168.143.162.36 assets0.twitter.com
168.143.162.36 assets1.twitter.com
168.143.162.36 assets2.twitter.com
168.143.162.36 assets3.twitter.com
168.143.162.36 static.twitter.com
168.143.162.36 twitter.zendesk.com
168.143.162.36 help.twitter.com

然后访问 https://twitter.com 即可。
]]></description>
			<content:encoded><![CDATA[<p>俺同学说得很经典，twitter被这么一封，更加代表一种文化了。由于twitter的100%的开放性，twitter已经衍生出非常多的有趣应用。twitter的口号也已经从展示大家在做什么，改成了“Share and discover what’s happening right now, anywhere in the world.”，这表明twitter正在超更有意义的方向前进，从大家谈论吃饭睡觉的垃圾信息广播站，变成了一个分享即时信息的巨大平台。</p>
<p>虽然现在twitter在国内被盾了，但是由于它的开发性，很容易构建其他的twitter中转服务器，所以GFW是无法通过封禁域名和IP来堵住twitter的消息广播的，比如<strong>访问本域名下二级子域名t</strong>，就可以访问twitter。当然，现在也可以通过<a href="http://www.douban.com/group/topic/7964022" class="liexternal">修改hosts</a>来访问twitter。</p>
<p>你可以使用web、PC客户端或者手机等各种方式来访问twitter。如果你在手机上使用twitter的客户端，那么Direct Message甚至可以完全代替短信了，而且Direct Message是保存在twitter服务器上的，只要有网络的地方你就可以访问。和twitter一起流行的还有URL shortening和图片存储服务，目前我觉得比较好用的是<a href="http://is.gd" class="liexternal">http://is.gd</a>和<a href="http://yforg.com" class="liexternal">http://yforg.com</a>。一般的客户端可以自定义这两个服务器，以及twitter的中转服务器。</p>
<p>twitter的手机客户端多如牛毛，这里我推荐两个iphone上的客户端，一款是<a href="http://itunes.apple.com/us/app/twitterrific-premium/id284542696?mt=8" class="liexternal">Twitterrific</a>，我觉得它比流行的Tweeite优越的地方在于打开的时候会有新消息提醒，但是这款软件是没有push notification的，另外一款是<a href="http://itunes.apple.com/us/app/twitbird-twitter-push-notification/id317777108?mt=8" class="liexternal">Twitbird</a>，这款软件带push notification，不过有个不幸的消息，我在使用的过程中，发觉只支持未Jailbreak的iphone <img src='http://erera.net/wordpress/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>总之，twitter可以超级方便的分享自己的状态，记录身边有意义的事件，配合手机客户端的话还可以即时分享拍摄的图片，更新自己的位置等等；利用@，retweet等功能，可以很方便和朋友联系，在自己的圈子里发布消息公告等等，这点和即将流行的Google Wave也有异曲同工之妙。而且这些功能都是twitter在这两三年的发展中逐渐演化而来的，100% open的twitter还在不断进化中，可以预料它在未来会更加有趣和精彩。而我们唯一所需要做的，就是加入twitter，越多的朋友加入，将有越多的信息分享，越紧密的联系沟通，让我们一起推吧。</p>
<p>我的twitter：<a href="https://twitter.com/erera" class="liexternal">https://twitter.com/erera</a><br />
<span id="more-373"></span><br />
<strong>访问twitter官方站点的办法</strong><br />
把下边的内容加入hosts文件：</p>
<pre>
168.143.162.36 www.twitter.com
168.143.162.36 twitter.com
168.143.162.36 assets0.twitter.com
168.143.162.36 assets1.twitter.com
168.143.162.36 assets2.twitter.com
168.143.162.36 assets3.twitter.com
168.143.162.36 static.twitter.com
168.143.162.36 twitter.zendesk.com
168.143.162.36 help.twitter.com
</pre>
<p>然后访问 <a href="https://twitter.com" class="liexternal">https://twitter.com</a> 即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/lets-twitter.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在ubuntu上使用LaTeX</title>
		<link>http://erera.net/blog/texlive-ubuntu.html</link>
		<comments>http://erera.net/blog/texlive-ubuntu.html#comments</comments>
		<pubDate>Tue, 17 Nov 2009 02:51:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[自由&开源]]></category>
		<category><![CDATA[texlive]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://erera.net/?p=365</guid>
		<description><![CDATA[拜ubuntu的开发人员和apt所赐，现在在Linux上使用LaTeX已经变得非常方便了。只需要敲击如下命令就可以安装上texlive和中文支持了：

$ sudo aptitude install texlive latex-cjk-chinese

默认会安装arphic的几种中文字体。如果觉得不够漂亮，我这里有一些已经生成的中文字体包（水木TeX版的某大侠制作，适合打印，应该是我06年从他发布的某个包里提取出来的 ~110MB；如果你喜欢自己生成字体，参考附录第二篇文章），可以直接解压到HOME目录使用，包括了7种常用的中文字体：仿宋 fs, 黑体 hei, 楷体 kai, 隶书 li, 宋体 song, 宋体粗体 songb, 幼圆 you。使用有问题的话运行一下 update-updmap，更新目录信息。
安装完后，测试是否可以正确输出UTF8中文文档：

\documentclass{article}
\usepackage{CJK}
\begin{document}
\begin{CJK*}{UTF8}{song}
您好,texlive中文
\end{CJK*}
\end{document}

这里有几篇文章可以参考：

Ubuntu+Texlive+CJK 
TeXLive 2007 CJK Chinese Howto(zz)
LaTeX字体说明

]]></description>
			<content:encoded><![CDATA[<p>拜ubuntu的开发人员和apt所赐，现在在Linux上使用LaTeX已经变得非常方便了。只需要敲击如下命令就可以安装上texlive和中文支持了：</p>
<pre>
$ sudo aptitude install texlive latex-cjk-chinese
</pre>
<p>默认会安装arphic的几种中文字体。如果觉得不够漂亮，我这里有一些已经生成的<a href="http://dl.dropbox.com/u/288200/texmf.tgz" class="liexternal">中文字体包</a>（水木TeX版的某大侠制作，适合打印，应该是我06年从他发布的某个包里提取出来的 ~110MB；如果你喜欢自己生成字体，参考附录第二篇文章），可以直接解压到HOME目录使用，包括了7种常用的中文字体：仿宋 <code>fs</code>, 黑体 <code>hei</code>, 楷体 <code>kai</code>, 隶书 <code>li</code>, 宋体 <code>song</code>, 宋体粗体 <code>songb</code>, 幼圆 <code>you</code>。使用有问题的话运行一下 <code>update-updmap</code>，更新目录信息。</p>
<p>安装完后，测试是否可以正确输出UTF8中文文档：</p>
<pre>
\documentclass{article}
\usepackage{CJK}
\begin{document}
\begin{CJK*}{UTF8}{song}
您好,texlive中文
\end{CJK*}
\end{document}
</pre>
<p>这里有几篇文章可以参考：</p>
<ul>
<li><a href="http://hi.baidu.com/tty0/blog/item/f9583603acab3fe408fa93d2.html" class="liexternal">Ubuntu+Texlive+CJK </a></li>
<li><a href="http://junist.googlepages.com/wiki%3Atexlive2007cjkchinesehowto%28zz%29" class="liexternal">TeXLive 2007 CJK Chinese Howto(zz)</a></li>
<li><a href="http://junist.googlepages.com/latex.html" class="liexternal">LaTeX字体说明</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/texlive-ubuntu.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ubuntu 9.04 jaunty desktop effect lag</title>
		<link>http://erera.net/blog/ubuntu-jaunty-desktop-effect-lag.html</link>
		<comments>http://erera.net/blog/ubuntu-jaunty-desktop-effect-lag.html#comments</comments>
		<pubDate>Sat, 05 Sep 2009 16:05:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[自由&开源]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://erera.net/?p=339</guid>
		<description><![CDATA[最近在ubuntu下打开了composite显示效果，结果发觉在最大最小化和Alt-Tab的时候居然会lag几秒。心里郁闷，本子显卡是ATI HD3470，应该不会这样啊。于是放狗搜了一下，居然是个Xorg已知bug。
对于ATI显卡，在Gnome、KDE或其他WM上，都有这个问题，本来Xorg早有patch了，但是ubuntu 9.04里似乎居然没有集成进去。可以在源列表里加入如下源：
deb http://ppa.launchpad.net/ubuntu-x-swat/xserver-no-backfill/ubuntu jaunty main
deb-src http://ppa.launchpad.net/ubuntu-x-swat/xserver-no-backfill/ubuntu jaunty main
认证密钥如下：
sudo apt-key adv --recv-keys --keyserver keyserver.Ubuntu.com 0x643dc6bd56580ceb1ab4a9f63b22ab97af1cdfa9
sudo aptitude safe-upgrade后重启X，发觉X Window在切换窗口的时候已经流畅了。
]]></description>
			<content:encoded><![CDATA[<p>最近在ubuntu下打开了composite显示效果，结果发觉在最大最小化和Alt-Tab的时候居然会lag几秒。心里郁闷，本子显卡是ATI HD3470，应该不会这样啊。于是放狗搜了一下，居然是个<a href="https://bugs.launchpad.net/ubuntu/+source/fglrx-installer/+bug/351186" class="liexternal">Xorg已知bug</a>。</p>
<p>对于ATI显卡，在Gnome、KDE或其他WM上，都有这个问题，本来Xorg早有patch了，但是ubuntu 9.04里似乎居然没有集成进去。可以在源列表里加入<a href="https://launchpad.net/~ubuntu-x-swat/+archive/xserver-no-backfill" class="liexternal">如下源</a>：</p>
<pre>deb http://ppa.launchpad.net/ubuntu-x-swat/xserver-no-backfill/ubuntu jaunty main
deb-src http://ppa.launchpad.net/ubuntu-x-swat/xserver-no-backfill/ubuntu jaunty main</pre>
<p>认证密钥如下：</p>
<pre>sudo apt-key adv --recv-keys --keyserver keyserver.Ubuntu.com 0x643dc6bd56580ceb1ab4a9f63b22ab97af1cdfa9</pre>
<p><code>sudo aptitude safe-upgrade</code>后重启X，发觉X Window在切换窗口的时候已经流畅了。</p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/ubuntu-jaunty-desktop-effect-lag.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>折腾一下系统</title>
		<link>http://erera.net/blog/system-setup.html</link>
		<comments>http://erera.net/blog/system-setup.html#comments</comments>
		<pubDate>Sun, 30 Aug 2009 17:07:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[自由&开源]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://erera.net/?p=335</guid>
		<description><![CDATA[周末球友出差，没有打成球，于是宅在家里到半夜，突然脑袋一热就犯了IT民工的毛病。本来我已经渐渐修炼到，心中有系统，手头无系统的返璞归真之境界，无奈还要偶尔玩一玩。遂把心得小结如下：
首先是启动系统的工具，要启动系统，肯定得先有启动光碟啊。不过由于俺们越来越懒散，已经不知道多久没有见过启动光碟了，手头只有几个USB碟。不过有了这个就足够啦，推荐一个好玩的开源工具：UNetbootin，它目前支持基本所有的主流非主流的Linux系统，直接下载你要安装的ISO，利用这个工具灌装到USB碟里就能启动机器啦，你可以启动一个Live Linux，或者安装Linux，随便你了。
不过你没看错，它只是Linux工具，如果你要用USB安装Windows，那可以用这个工具：usboot，这个链接里的工具包括了一个ghost镜像，可以通过USB恢复Windows镜像，太方便了。另外还有个著名的PE-Builder，提供一个Live Windows，就跟那个深山红叶光碟差不多啦，既然已经能启动一个Linux Windows，那能干的事情就由你想象了。
装完系统后，关键问题就是如何联网了。说明一下连接无线的办法，如果你安装的系统还没有安装X环境，那建议使用HP的wireless tools，来连接无线网络。连接常见的WEP加密网络的步骤是：
# iwconfig wlan0 essid "wlan name"
# iwconfig wlan0 key s:"wlan password"
# dhclient wlan0
这样就可以自动获取IP了，如果不知道无线网络的名字，使用iwlist wlan0 scanning查一下。这部分代码也可以写到 /etc/network/interfaces里：
if-pre /sbin/iwconfig wlan0 essid "wlan name"
if-pre /sbin/iwconfig wlan0 key s:"wlan password"
iface wlan0 inet dhcp
这样系统装好了，网络也没问题了，然后就随便干什么事情啦，over。

贴几个ubuntu 9.04的源：

ibus: deb http://ppa.launchpad.net/ibus-dev/ppa/ubuntu jaunty main
Medibuntu: deb http://packages.medibuntu.org/ jaunty free non-free
wineHQ: deb http://wine.budgetdedicated.com/apt jaunty main
Gnome-do: deb http://ppa.launchpad.net/do-core/ppa/ubuntu jaunty main
Chrome: deb http://dl.google.com/linux/deb/ stable main

Defining [...]]]></description>
			<content:encoded><![CDATA[<p>周末球友出差，没有打成球，于是宅在家里到半夜，突然脑袋一热就犯了IT民工的毛病。本来我已经渐渐修炼到，心中有系统，手头无系统的返璞归真之境界，无奈还要偶尔玩一玩。遂把心得小结如下：</p>
<p>首先是启动系统的工具，要启动系统，肯定得先有启动光碟啊。不过由于俺们越来越懒散，已经不知道多久没有见过启动光碟了，手头只有几个USB碟。不过有了这个就足够啦，推荐一个好玩的开源工具：<a href="http://unetbootin.sourceforge.net/" class="liexternal">UNetbootin</a>，它目前支持基本所有的主流非主流的Linux系统，直接下载你要安装的ISO，利用这个工具灌装到USB碟里就能启动机器啦，你可以启动一个Live Linux，或者安装Linux，随便你了。</p>
<p>不过你没看错，它只是Linux工具，如果你要用USB安装Windows，那可以用这个工具：<a href="http://junist.googlepages.com/usboot1.7_for_ghost.zip" class="lizip">usboot</a>，这个链接里的工具包括了一个ghost镜像，可以通过USB恢复Windows镜像，太方便了。另外还有个著名的<a href="http://www.nu2.nu/pebuilder/" class="liexternal">PE-Builder</a>，提供一个Live Windows，就跟那个深山红叶光碟差不多啦，既然已经能启动一个Linux Windows，那能干的事情就由你想象了。</p>
<p>装完系统后，关键问题就是如何联网了。说明一下连接无线的办法，如果你安装的系统还没有安装X环境，那建议使用HP的<a href="http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html" class="liexternal">wireless tools</a>，来连接无线网络。连接常见的WEP加密网络的步骤是：</p>
<pre># iwconfig wlan0 essid "wlan name"
# iwconfig wlan0 key s:"wlan password"
# dhclient wlan0</pre>
<p>这样就可以自动获取IP了，如果不知道无线网络的名字，使用<code>iwlist wlan0 scanning</code>查一下。这部分代码也可以写到 <code>/etc/network/interfaces</code>里：</p>
<pre>if-pre /sbin/iwconfig wlan0 essid "wlan name"
if-pre /sbin/iwconfig wlan0 key s:"wlan password"
iface wlan0 inet dhcp</pre>
<p>这样系统装好了，网络也没问题了，然后就随便干什么事情啦，over。</p>
<p><span id="more-335"></span></p>
<p>贴几个ubuntu 9.04的源：</p>
<ul>
<li>ibus: <code>deb http://ppa.launchpad.net/ibus-dev/ppa/ubuntu jaunty main</code></li>
<li>Medibuntu: <code>deb http://packages.medibuntu.org/ jaunty free non-free</code></li>
<li>wineHQ: <code>deb http://wine.budgetdedicated.com/apt jaunty main</code></li>
<li>Gnome-do: <code>deb http://ppa.launchpad.net/do-core/ppa/ubuntu jaunty main</code></li>
<li>Chrome: <code>deb http://dl.google.com/linux/deb/ stable main</code></li>
</ul>
<h3>Defining physical interfaces such as eth0</h3>
<p>Lines beginning with the word "auto" in config file <code>/etc/network/interfaces</code> are used to identify the physical interfaces to be brought up when ifup is run with the -a option. (This option is used by the system boot scripts.) Physical interface names should follow the word "auto" on the same line. There can be multiple "auto" stanzas. ifup brings the named inter faces up in the order listed. For example following example setup eth0 (first network interface card) with 192.168.1.5 IP address and gateway (router) to 192.168.1.254:</p>
<pre>
iface eth0 inet static
address 192.168.1.5
netmask 255.255.255.0
gateway 192.168.1.254
</pre>
<h3>Setup interface to dhcp</h3>
<pre>
auto eth0
iface eth0 inet dhcp
</pre>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/system-setup.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>完美藏在细节里(iphone vs. X1)</title>
		<link>http://erera.net/blog/detail-makes-iphone-win.html</link>
		<comments>http://erera.net/blog/detail-makes-iphone-win.html#comments</comments>
		<pubDate>Sun, 26 Jul 2009 15:56:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[数码控]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://erera.net/?p=330</guid>
		<description><![CDATA[自从上个月丢了用了2年多的treo680，就开始无所适从，不知道选啥机器好了。后来想想试试wm系统吧，于是挑来挑去选择了SE X1。
用了1个月的X1，发觉这机器的做工的确无与伦比，全金属外壳，全金属的侧滑键盘，尤其是银色款，非常的精致漂亮，握在手上超级有质感。对比一代的iphone是不遑多让，而且也不用保护套啥的，磨砂工艺的金属外壳，根本不用担心被划伤。另外让人惊喜的是，电话的通话质量奇佳，而且使用1500mha电池，正常使用都可以待机3天。内部硬件上同样很牛x，CPU比touch HD还好，800x480的屏幕，细腻得不行，并且跑wm6.1的时候，程序运行速度不错。
但是，唯一可惜的是，wm系统实在难用。给我印象最深的是，某次我收到一条陌生人的短信，我想给他回复电话，我想当然的像treo那样按电话键居然没成功；后来找了半天菜单也没个回复电话的功能，最终是存成联系人，然后再拨号的，这点实在太囧了。难怪HTC要给wm做一套manila的界面，因为wm虽然看起来很强大，但是易用性和细节方面的确有待商榷。一个简单的回复电话都要数次菜单和点击才能完成，这样的手机使用起来实在是浪费生命。
这其中我就开始考虑其他机型，也试用过朋友的G1，发觉andriod用起来还是蛮方便的，不过不是很喜欢那个强力弹出的键盘，并且耗电也很厉害。本来也很巴望palm pre，可惜GSM的版本还不知道在哪里。最后考虑了iphone，并且刚好现在出了3gs，运行速度对比iphone 3g有了不小改善。
使用了一段时间，发觉3gs无论软件还是硬件上很多细节都比x1好多了，尤其那个耳机做的非常的惊艳，一个小小的控制器就可以控制音乐播放、音量调节，甚至可以接拨电话。最近使用了电话、短信、邮箱和浏览器，在易用性上均超过了wm系统，尤其是safari的多点触摸在浏览网页的时候非常方便，摇一摇机器就能清空短信也很有意思。另外感觉电容屏比电阻屏要灵敏多了，这在看电子书翻页的时候体验很好。3gs新增的语音拨号准确程度出乎意料，这个很好用，基本不用翻电话簿了，想念起palm的中文伴侣搭配qwerty键盘的快捷，语音拨号也算独辟蹊径呵。总之，iphone os的用户体验就像mac os x那样，各个程序衔接很流畅，有浑然一体的感觉，不像windows系统，虽然强大，可选择性很多，但程序和程序直接拼凑痕迹严重，时不时的就掉了链子。
缺点就是3gs屏幕分辨率比X1要逊色不少，看惯了X1的屏幕上的true type字体，觉得3gs的字体显示真是挫死了，坑坑洼洼的。真不知道apple想等到第几代机器再换屏幕，估计届时又是得大大吹嘘一通，然后哗哗收钱。
就目前一两天的使用来看，iphone os体验不错，很期待wm7有所改善。常常说魔鬼藏在细节里，完美也藏在细节里。在完美程度上，X1的硬件可以打95分，wm可以打70分，而3gs硬件可以打90分，iphone os可以打90分，哈哈
]]></description>
			<content:encoded><![CDATA[<p>自从上个月丢了用了2年多的treo680，就开始无所适从，不知道选啥机器好了。后来想想试试wm系统吧，于是挑来挑去选择了SE X1。</p>
<p>用了1个月的X1，发觉这机器的做工的确无与伦比，全金属外壳，全金属的侧滑键盘，尤其是银色款，非常的精致漂亮，握在手上超级有质感。对比一代的iphone是不遑多让，而且也不用保护套啥的，磨砂工艺的金属外壳，根本不用担心被划伤。另外让人惊喜的是，电话的通话质量奇佳，而且使用1500mha电池，正常使用都可以待机3天。内部硬件上同样很牛x，CPU比touch HD还好，800x480的屏幕，细腻得不行，并且跑wm6.1的时候，程序运行速度不错。</p>
<p>但是，唯一可惜的是，wm系统实在难用。给我印象最深的是，某次我收到一条陌生人的短信，我想给他回复电话，我想当然的像treo那样按电话键居然没成功；后来找了半天菜单也没个回复电话的功能，最终是存成联系人，然后再拨号的，这点实在太囧了。难怪HTC要给wm做一套manila的界面，因为wm虽然看起来很强大，但是易用性和细节方面的确有待商榷。一个简单的回复电话都要数次菜单和点击才能完成，这样的手机使用起来实在是浪费生命。</p>
<p>这其中我就开始考虑其他机型，也试用过朋友的G1，发觉andriod用起来还是蛮方便的，不过不是很喜欢那个强力弹出的键盘，并且耗电也很厉害。本来也很巴望palm pre，可惜GSM的版本还不知道在哪里。最后考虑了iphone，并且刚好现在出了3gs，运行速度对比iphone 3g有了不小改善。</p>
<p>使用了一段时间，发觉3gs无论软件还是硬件上很多细节都比x1好多了，尤其那个耳机做的非常的惊艳，一个小小的控制器就可以控制音乐播放、音量调节，甚至可以接拨电话。最近使用了电话、短信、邮箱和浏览器，在易用性上均超过了wm系统，尤其是safari的多点触摸在浏览网页的时候非常方便，摇一摇机器就能清空短信也很有意思。另外感觉电容屏比电阻屏要灵敏多了，这在看电子书翻页的时候体验很好。3gs新增的语音拨号准确程度出乎意料，这个很好用，基本不用翻电话簿了，想念起palm的中文伴侣搭配qwerty键盘的快捷，语音拨号也算独辟蹊径呵。总之，iphone os的用户体验就像mac os x那样，各个程序衔接很流畅，有浑然一体的感觉，不像windows系统，虽然强大，可选择性很多，但程序和程序直接拼凑痕迹严重，时不时的就掉了链子。</p>
<p>缺点就是3gs屏幕分辨率比X1要逊色不少，看惯了X1的屏幕上的true type字体，觉得3gs的字体显示真是挫死了，坑坑洼洼的。真不知道apple想等到第几代机器再换屏幕，估计届时又是得大大吹嘘一通，然后哗哗收钱。</p>
<p>就目前一两天的使用来看，iphone os体验不错，很期待wm7有所改善。常常说魔鬼藏在细节里，完美也藏在细节里。在完美程度上，X1的硬件可以打95分，wm可以打70分，而3gs硬件可以打90分，iphone os可以打90分，哈哈</p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/detail-makes-iphone-win.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>狗X的GFW</title>
		<link>http://erera.net/blog/fuck-gfw.html</link>
		<comments>http://erera.net/blog/fuck-gfw.html#comments</comments>
		<pubDate>Fri, 24 Jul 2009 02:19:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[gfw]]></category>

		<guid isPermaLink="false">http://erera.net/?p=326</guid>
		<description><![CDATA[当然更该X的我不说大家也知道，整天不干好事，盾来盾去，不知道到底想怎么折腾。这回是picasaweb的图片服务器都被盾了，所以俺的两千来张照片就全都看不见了。不过还好有自我救赎的办法，执行下边一段脚本后就还能苟延残喘了；如果是Vista或者Win7，需要以Administrator权限执行。
&#19979;&#36733;: restore_picasa.bat@attrib %windir%\SYSTEM32\drivers\etc\hosts -r@echo 203.208.39.104 lh1.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts@echo 203.208.39.104 lh2.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts@echo 203.208.39.104 lh3.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts@echo 203.208.39.104 lh4.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts@echo 203.208.39.104 lh5.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts@echo 203.208.39.104 lh6.ggpht.com &#62;&#62; %windir%\SYSTEM32\drivers\etc\hosts

为了排遣一下抑郁的心情，重温一下阿Q的精神，给童鞋们转载篇动物世界的故事：
　　在荒茫而美丽的马勒戈壁上。生活着一群顽强的草泥马。（因为草泥马实是主要物种，所以马勒戈壁又叫草泥马戈壁）草泥马们克服了戈壁的艰苦环境，并顽强的生活下来。戈壁上缺少水缺少食物，草泥马能进食的只有一种草——卧草。然而卧草一般生长在人类的聚集点附近。所以草泥马一生都是于人类相依为伴的。
　　在一个草泥马群居点。笔者认识了朝泥族青年，朝泥两次。他告诉笔者部族里只有成年男性才可以配有一匹草泥马。草泥马分为三个品质。最下等才叫做草泥马。中等的叫做卧槽泥马。而最上等的是狂槽泥马。狂槽泥马是马王，要部族里骑术最好的人才能获得。朝泥两次说自己因为骑术好。还没成年的时候就获得了狂槽泥马。说完他立刻露出的腼腆的笑容。随即笔者来到了朝泥两次的家。他的母亲热情接待了我们。喝了些许马奶，就到了睡着了。醒来后发现朝泥两次的父亲朝泥大爷也回到了家。我便跟朝泥大爷聊了起来。朝泥大爷显现出了忧伤的表情：“日子不好过了，我们家以前是买马匹的。现在改行割皮包了。因为草泥马吃的食物卧草几乎全被一种叫河蟹的动物吃掉了。他说他也不知道河蟹是怎么来的。但是随着食物的减少。草泥马数量也在急剧减少。”说罢流下了痛心的眼泪。
　　鲜红的晚霞和岩石如同一对轻骑。护送笔者离开马勒戈壁，在缓缓的落日下看着一群一群的草泥马湮没在沙尘之中。或许如果不保护环境。最后倒下的必将是人类。
]]></description>
			<content:encoded><![CDATA[<p>当然更该X的我不说大家也知道，整天不干好事，盾来盾去，不知道到底想怎么折腾。这回是picasaweb的图片服务器都被盾了，所以俺的两千来张照片就全都看不见了。不过还好有自我救赎的办法，执行下边一段脚本后就还能苟延残喘了；如果是Vista或者Win7，需要以Administrator权限执行。</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erera.net/wordpress/wp-content/plugins/coolcode/coolcode.php?p=326&amp;download=restore_picasa.bat">restore_picasa.bat</a></div><div class="hl-surround"><div class="hl-main">@attrib %windir%\SYSTEM32\drivers\etc\hosts -r<br />@echo 203.208.39.104 lh1.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts<br />@echo 203.208.39.104 lh2.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts<br />@echo 203.208.39.104 lh3.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts<br />@echo 203.208.39.104 lh4.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts<br />@echo 203.208.39.104 lh5.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts<br />@echo 203.208.39.104 lh6.ggpht.com &gt;&gt; %windir%\SYSTEM32\drivers\etc\hosts</div></div>
<p><span id="more-326"></span><br />
为了排遣一下抑郁的心情，重温一下阿Q的精神，给童鞋们转载篇动物世界的故事：</p>
<blockquote><p>　　在荒茫而美丽的马勒戈壁上。生活着一群顽强的草泥马。（因为草泥马实是主要物种，所以马勒戈壁又叫草泥马戈壁）草泥马们克服了戈壁的艰苦环境，并顽强的生活下来。戈壁上缺少水缺少食物，草泥马能进食的只有一种草——卧草。然而卧草一般生长在人类的聚集点附近。所以草泥马一生都是于人类相依为伴的。</p>
<p>　　在一个草泥马群居点。笔者认识了朝泥族青年，朝泥两次。他告诉笔者部族里只有成年男性才可以配有一匹草泥马。草泥马分为三个品质。最下等才叫做草泥马。中等的叫做卧槽泥马。而最上等的是狂槽泥马。狂槽泥马是马王，要部族里骑术最好的人才能获得。朝泥两次说自己因为骑术好。还没成年的时候就获得了狂槽泥马。说完他立刻露出的腼腆的笑容。随即笔者来到了朝泥两次的家。他的母亲热情接待了我们。喝了些许马奶，就到了睡着了。醒来后发现朝泥两次的父亲朝泥大爷也回到了家。我便跟朝泥大爷聊了起来。朝泥大爷显现出了忧伤的表情：“日子不好过了，我们家以前是买马匹的。现在改行割皮包了。因为草泥马吃的食物卧草几乎全被一种叫河蟹的动物吃掉了。他说他也不知道河蟹是怎么来的。但是随着食物的减少。草泥马数量也在急剧减少。”说罢流下了痛心的眼泪。</p>
<p>　　鲜红的晚霞和岩石如同一对轻骑。护送笔者离开马勒戈壁，在缓缓的落日下看着一群一群的草泥马湮没在沙尘之中。或许如果不保护环境。最后倒下的必将是人类。</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/fuck-gfw.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>部署小型软件项目开发管理平台</title>
		<link>http://erera.net/blog/pm-platform.html</link>
		<comments>http://erera.net/blog/pm-platform.html#comments</comments>
		<pubDate>Tue, 02 Jun 2009 16:37:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开发学习]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://erera.net/?p=315</guid>
		<description><![CDATA[介绍
一个软件项目的开发一般包括文档管理、代码管理、版本管理、进度管理、bug管理等，这方面的支持工具也很多。我觉得Trac是一个很优秀的代表，用它搭配SVN作为前端工作，差不多可以把这些任务都顺利解决了。Trac有如下一些特点：
ticket
Trac利用ticket的概念，把feature提交、task分配以及bug管理很完美的整合到了一起。

可以设置ticket的优先
ticket和roadmap结合，并且能够图形化显示项目进度
自定义条件生成bug报告

wiki
wiki功能贯穿在整个工具里，可以很方便的组织说明文档。同时增加了许多bug管理的专用标记，能方便的创建到ticket、代码行甚至修改历史的链接。
subversion
Trac可以作为subversion的前端，和svn搭配得很好。比如可以在timeline中看到所有的提交记录，可以在source view里方便的对比历史版本，并且具备语法高亮。

部署
Trac是基于python的，安装它之前需要python、apache、subversion、openssh、sqlite、swig等一坨软件的支持。幸运的是，得益于apt包管理系统，在ubuntu或者debian环境下搭建和配置这样一个管理平台也很容易，几行命令就可以搞定。
aptitude install trac apache2 subversion python swig
aptitude install mod_python python-clearsilver libapache2-svn
就是这么简单，如果在fedora、centos之类就要费点劲了。（建议安装trac-0.11.x 之后的版本，因为其中的admin模块会比较好用）
配置
接下来就是配置trac系统，我觉得其中的权限设置可以有一些技巧。首先，对于开发人员，最好使用独立的组，比如 devteam，比如我的帐号和组分别就是 julian:devteam。
配置subversion
这样在为svn创建独立用户的时候，也可以把该svn用户归到devteam中；当然其中svnroot可以不用重设密码，如果不打算登录该用户的话。
# groupadd devteam
# useradd svnroot -g devteam -s /usr/sbin/nologin
# passwd svnroot
在home目录下为svn开辟一个目录，用来放置代码仓库。然后，创建代码仓库，比如 test，默认为 fsfs 文件格式。
# mkdir -p /home/svnroot/
# svnadmin create /home/svnroot/test
# chown -R svnroot:devteam /home/svnroot
# chmod -R g+w /home/svnroot/test
# chmod g+s /home/svnroot/test/db
HTTP方式的配置
这一步为可选。如果你期望通过DAV模块，以HTTP方式管理代码的话（比如google code提供的svn服务），可以在apache下添加如下站点设置：
# cat > /etc/apache2/sites-available/svn
然后添加如下内容：
### svn settings
#
&#60;Location /svn&#62;
    [...]]]></description>
			<content:encoded><![CDATA[<h2>介绍</h2>
<p>一个软件项目的开发一般包括文档管理、代码管理、版本管理、进度管理、bug管理等，这方面的支持工具也很多。我觉得Trac是一个很优秀的代表，用它搭配SVN作为前端工作，差不多可以把这些任务都顺利解决了。Trac有如下一些特点：</p>
<h3>ticket</h3>
<p>Trac利用ticket的概念，把feature提交、task分配以及bug管理很完美的整合到了一起。</p>
<ul>
<li>可以设置ticket的优先</li>
<li>ticket和roadmap结合，并且能够图形化显示项目进度</li>
<li>自定义条件生成bug报告</li>
</ul>
<h3>wiki</h3>
<p>wiki功能贯穿在整个工具里，可以很方便的组织说明文档。同时增加了许多bug管理的专用标记，能方便的创建到ticket、代码行甚至修改历史的链接。</p>
<h3>subversion</h3>
<p>Trac可以作为subversion的前端，和svn搭配得很好。比如可以在timeline中看到所有的提交记录，可以在source view里方便的对比历史版本，并且具备语法高亮。<br />
<span id="more-315"></span></p>
<h2>部署</h2>
<p>Trac是基于python的，安装它之前需要python、apache、subversion、openssh、sqlite、swig等一坨软件的支持。幸运的是，得益于apt包管理系统，在ubuntu或者debian环境下搭建和配置这样一个管理平台也很容易，几行命令就可以搞定。</p>
<pre>aptitude install trac apache2 subversion python swig
aptitude install mod_python python-clearsilver libapache2-svn</pre>
<p>就是这么简单，如果在fedora、centos之类就要费点劲了。（建议安装trac-0.11.x 之后的版本，因为其中的admin模块会比较好用）</p>
<h2>配置</h2>
<p>接下来就是配置trac系统，我觉得其中的权限设置可以有一些技巧。首先，对于开发人员，最好使用独立的组，比如 <code>devteam</code>，比如我的帐号和组分别就是 <code>julian:devteam</code>。</p>
<h3>配置subversion</h3>
<p>这样在为svn创建独立用户的时候，也可以把该svn用户归到devteam中；当然其中svnroot可以不用重设密码，如果不打算登录该用户的话。</p>
<pre># groupadd devteam
# useradd svnroot -g devteam -s /usr/sbin/nologin
# passwd svnroot</pre>
<p>在home目录下为svn开辟一个目录，用来放置代码仓库。然后，创建代码仓库，比如 test，默认为 fsfs 文件格式。</p>
<pre># mkdir -p /home/svnroot/
# svnadmin create /home/svnroot/test
# chown -R svnroot:devteam /home/svnroot
# chmod -R g+w /home/svnroot/test
# chmod g+s /home/svnroot/test/db</pre>
<h3>HTTP方式的配置</h3>
<p>这一步为可选。如果你期望通过DAV模块，以HTTP方式管理代码的话（比如<a href="http://code.google.com" class="liexternal">google code</a>提供的svn服务），可以在apache下添加如下站点设置：</p>
<pre># cat > /etc/apache2/sites-available/svn</pre>
<p>然后添加如下内容：</p>
<pre>### svn settings
#
&lt;Location /svn&gt;
    DAV svn
    SVNListParentPath on
    SVNParentPath /home/svnroot
    AuthType Basic
    AuthName "Subversion Repository"
    AuthUserFile /etc/apache2/svntrac.htpasswd
    &lt;LimitExcept GET PROPFIND OPTIONS REPORT&gt;
        Require valid-user
    &lt;/LimitExcept&gt;
&lt;/Location&gt;</pre>
<p>一些说明：</p>
<ul>
<li><code>SVNListParentPath on</code>  允许在网页上显示svn父目录list</li>
<li><code>SVNParentPath /home/svnroot</code> SVN的父目录</li>
<li><code>AuthType Basic</code> 连接类型设置</li>
<li><code>LimitExcept</code> 匿名用户可以浏览，check out代码，但是不能commit，认证用户有commit权限</li>
</ul>
<p>然后把这个新加的站点激活：</p>
<pre># cd /etc/apache2/site-enabled
# ln -s ../site-available/svn 001-svn</pre>
<h4>为http方式添加svn用户和密码</h4>
<p>使用htpasswd创建第一个svn用户，比如用户名为 julian （第一次创建需要 -c 参数）</p>
<pre># htpasswd -c /etc/apache2/svntrac.htpasswd julian</pre>
<h4>修改apache启动方式</h4>
<p>为了让apache可以管理svn代码，需要apache进程对svn目录有读写权限，所以需要更改apache的启动用户组，比如也改成<code>svnroot:devteam</code>，或者至少组改成一致的。</p>
<pre># vim /etc/apache2/envvars</pre>
<p>修改其中的用户 <code>APACHE_RUN_USER</code> 和组 <code>APACHE_RUN_GROUP</code>，然后重启apache，尝试是否已经可以通过 <a href="http://localhost/svn" class="liexternal">http://localhost/svn</a> 访问svn代码仓库。</p>
<h3>仓库目录和项目导入</h3>
<p>为了今后项目管理的更加方便，一个技巧是，不要直接导入项目代码，而是首先划分出三个目录 trunk、tags和branches，初始项目代码放在trunk目录下。</p>
<pre># mkdir /tmp/svn
# cd /tmp/svn
# mkdir {trunk,tags,branches}
# svn import -m "my project init here" [path] http://localhost/svn/test</pre>
<p>这就创建了第一个版本，在import之后可以用checkout命令测试一下，就该可以check out刚才import的代码了。</p>
<pre>svn co http://localhost/svn/test/trunk</pre>
<h3>SVN+SSH方式的配置</h3>
<p>另外有一种更加简单的办法来进行代码管理，这几乎完全不需要像HTTP那样的复杂配置。只要安装了subversion和sshd服务，就可以使用svn+ssh方式来管理代码。这个过程其实是你先连接到sshd服务器，然后sshd进程再调用svnserve进程来管理代码。例如，你要check out代码，就可以这样：</p>
<pre>svn co svn+ssh://svn_server/home/svnroot/test/trunk</pre>
<p>这种方式和HTTP的主要差别有这样两点：</p>
<ul>
<li>需要说明代码仓库所在的全路径，而不是http dav方式的虚拟地址</li>
<li>这种方式首先需要开发成员有ssh的权限，所以需要在主机上有一个对应的真实用户，而不像http dav方式使用htpasswd来管理的虚拟用户</li>
</ul>
<p>另外，如果sshd不是标准的22端口时候，有两种解决办法，一是在 <code>~/.ssh/config</code> 文件中配置好端口，比如：</p>
<pre>host svn_server
    Hostname svn_server
    Port 2022
    ForwardAgent no
    ForwardX11 no</pre>
<p>或者是通过环境变量解决：</p>
<pre>$ env SVN_SSH='ssh -p 2022" svn co svn+ssh://svn_server/home/svnroot/test/trunk</pre>
<h3>配置Trac</h3>
<h4>创建Trac项目</h4>
<p>使用 trac-admin 命令可以初始化一个trac项目，一个 trac 项目对应一个 SVN  repository。同样，可以在home目录下为trac建立对应的目录。</p>
<pre># mkdir /home/trac
# trac-admin /home/trac/test initenv</pre>
<p>然后按提示输入，一般只需要修改仓库路径，比如改为 <code>/home/svnroot/test</code></p>
<h4>集成apache服务</h4>
<p>Trac 有两种方式提供web服务，一是 trac 自带的 httpd 服务，二是集成到 apache 里面。</p>
<p>如果要用自带的 httpd，只需 <code>tracd --port 8000 /home/trac/test</code>，这种方式很简单，但 trac 本身就不建议这样启动。常用的应该是第二种方式.</p>
<p>首先确定你的 apache 配置 cgi-bin 的路径，比如<code>/usr/lib/cgi-bin/</code>，然后需要复制两个trac的cgi到该目录下：</p>
<pre># cp /usr/share/trac/cgi-bin/trac.* /usr/lib/cgi-bin/</pre>
<p>然后，你可以再新增加一个站点用于trac，比如：</p>
<pre># cat > /etc/apache2/sites-available/trac</pre>
<p>增加如下内容：</p>
<pre>Alias /trac/chrome/common "/usr/share/trac/htdocs"
&lt;Directory "/usr/share/trac/htdocs"&gt;
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
&lt;/Directory&gt;

ScriptAlias /trac /usr/lib/cgi-bin/trac.cgi
&lt;Location "/trac"&gt;
SetEnv TRAC_ENV_PARENT_DIR "/home/trac"
&lt;/Location&gt;

&lt;Location "/trac/*/login"&gt;
AuthType Basic
AuthName "Trac Login"
AuthUserFile /etc/apache2/svntrac.htpasswd
Require valid-user
&lt;/Location&gt;</pre>
<p>同样在 site-enabled 中激活该站点，然后重启apache即可。访问 http://localhost/trac，应该可以看到项目列表。因为密码文件是和svn共享的，所以用svn的用户名登录即可。</p>
<h3>权限管理</h3>
<p>用户权限可以使用Trac中的Admin模块管理，也可以使用<code>trac-admin</code>命令管理，后者使用更加便捷。其中一个技巧是不要直接把权限划分到个人，而是先划分组权限，然后再把用户加入不同的组，这类似RBAC的管理方式，例如：</p>
<pre># trac-admin /home/trac/test permission add devteam BROWSER_VIEW CHANGESET_VIEW CONFIG_VIEW FILE_VIEW LOG_VIEW MILESTONE_ADMIN REPORT_ADMIN ROADMAP_ADMIN ROADMAP_VIEW SEARCH_VIEW TICKET_ADMIN TIMELINE_VIEW WIKI_ADMIN
# trac-admin /home/trac/test permission add lancer devteam</pre>
<p>Trac中有默认的两个组 anonymous 和 authenticated，如果你不希望整个项目在互联网上公开，可以删除 anonymous 组，或者删除浏览权限 BROWSER_VIEW。</p>
<h3>备份和恢复Trac</h3>
<p>Trac系统的备份和恢复也可使用trac-admin工具来完成，还可支持热备份，例如：</p>
<pre># trac-admin /home/trac/test hotcopy ~/backup</pre>
<p>执行该命令时，Trac会自动锁住SQLite数据库，并把/home/trac/test目录拷贝到~/backup目录。恢复备份也很简单，只需停止Trac进程，如Apache服务器或tracd服务器。接着把~/backup整个目录恢复回/data/trac目录就可以了。</p>
<h2>客户端</h2>
<p>如果有喜欢使用IDE的，推荐这样的客户端搭配：eclipse + mylyn(trac) + subclipse</p>
<p>另外，在Windows下还有个很cool的客户端<a href="http://tortoisesvn.tigris.org/" class="liexternal">TortoiseSVN</a>，和资源管理器整合得很好。</p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/pm-platform.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]把STL容器放入共享内存</title>
		<link>http://erera.net/blog/creating-stl-containers-in-shared-memory.html</link>
		<comments>http://erera.net/blog/creating-stl-containers-in-shared-memory.html#comments</comments>
		<pubDate>Tue, 03 Feb 2009 08:16:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开发学习]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://erera.net/?p=299</guid>
		<description><![CDATA[昨天在上篇blog里描写了如何把STL容器放到共享内存里去，不过由于好久不写blog，发觉词汇组织能力差了很多，不少想写的东西写的很零散，今天刚好翻看自己的书签，看到一篇挺老的文章，不过从共享内存到STL容器讲述得蛮全面，还提供了学习的实例，所以顺便翻译过来，并附上原文地址。
共享内存(shm)是当前主流UNIX系统中的一种IPC方法，它允许多个进程把同一块物理内存段(segment)映射(map)到它们的地址空间中去。既然内存段对于各自附着(attach)的进程是共享的，这些进程可以很方便的通过这块共享内存上的共有数据进行通信。因此，顾名思义，共享内存就是进程之间共享的一组内存段。当一个进程附着到一块共享内存上后，它得到一个指向这块共享内存的指针；该进程可以像使用其他内存一样使用这块共享内存。当然，由于这块内存同样会被其他进程访问或写入，所以必须要注意进程同步问题。
参考如下代码，这是UNIX系统上使用共享内存的一般方法（注：本文调用的是POSIX函数）：

//Get shared memory id
//shared memory key
const&#160;key_t ipckey = 24568;&#160;&#160; 
//shared memory permission; can be
//read and written by anybody
const&#160;int perm = 0666;
//shared memory segment size
size_t&#160;shmSize = 4096;
//Create shared memory if not
//already created with specified
//permission
int&#160;shmId = shmget
&#160; (ipckey,shmSize,IPC_CREAT&#124;perm);
if&#160;(shmId ==-1) {
&#160; //Error
}
&#160;
//Attach the shared memory segment
&#160;
void* shmPtr = shmat(shmId,NULL,0);
&#160;
struct&#160;commonData* dp =&#160; (struct commonData*)shmPtr;
&#160;
//detach shared memory
shmdt(shmPtr);
存放在共享内存中的数据结构
当保存数据到共享内存中时需要留意，参考如下结构：
struct commonData {
&#160; int&#160;sharedInt;
&#160; [...]]]></description>
			<content:encoded><![CDATA[<p><em>昨天在上篇blog里描写了如何把STL容器放到共享内存里去，不过由于好久不写blog，发觉词汇组织能力差了很多，不少想写的东西写的很零散，今天刚好翻看自己的书签，看到一篇挺老的文章，不过从共享内存到STL容器讲述得蛮全面，还提供了学习的实例，所以顺便翻译过来，并附上<a href="http://www.ddj.com/cpp/184401639" class="liexternal">原文地址</a>。</em></p>
<p>共享内存(shm)是当前主流UNIX系统中的一种IPC方法，它允许多个进程把同一块物理内存段(segment)映射(map)到它们的地址空间中去。既然内存段对于各自附着(attach)的进程是共享的，这些进程可以很方便的通过这块共享内存上的共有数据进行通信。因此，顾名思义，共享内存就是进程之间共享的一组内存段。当一个进程附着到一块共享内存上后，它得到一个指向这块共享内存的指针；该进程可以像使用其他内存一样使用这块共享内存。当然，由于这块内存同样会被其他进程访问或写入，所以必须要注意进程同步问题。</p>
<p>参考如下代码，这是UNIX系统上使用共享内存的一般方法（注：本文调用的是POSIX函数）：<br />
<span id="more-299"></span></p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">//Get shared memory id</span></li>
<li><span style="color: #ffa500;">//shared memory key</span></li>
<li><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">key_t</span><span style="color: Gray;"> </span><span style="color: Blue;">ipckey</span><span style="color: Gray;"> = </span><span style="color: Maroon;">24568</span><span style="color: Gray;">;&nbsp;&nbsp; </span></li>
<li><span style="color: #ffa500;">//shared memory permission; can be</span></li>
<li><span style="color: #ffa500;">//read and written by anybody</span></li>
<li><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">int</span><span style="color: Gray;"> </span><span style="color: Blue;">perm</span><span style="color: Gray;"> = </span><span style="color: Maroon;">0666</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//shared memory segment size</span></li>
<li><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmSize</span><span style="color: Gray;"> = </span><span style="color: Maroon;">4096</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//Create shared memory if not</span></li>
<li><span style="color: #ffa500;">//already created with specified</span></li>
<li><span style="color: #ffa500;">//permission</span></li>
<li><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmId</span><span style="color: Gray;"> = </span><span style="color: Blue;">shmget</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">ipckey</span><span style="color: Gray;">,</span><span style="color: Blue;">shmSize</span><span style="color: Gray;">,</span><span style="color: Blue;">IPC_CREAT</span><span style="color: Gray;">|</span><span style="color: Blue;">perm</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;"> ==-</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: #ffa500;">//Error</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//Attach the shared memory segment</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">shmPtr</span><span style="color: Gray;"> = </span><span style="color: Blue;">shmat</span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">commonData</span><span style="color: Gray;">* </span><span style="color: Blue;">dp</span><span style="color: Gray;"> =&nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">commonData</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">shmPtr</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//detach shared memory</span></li>
<li><span style="color: Blue;">shmdt</span><span style="color: Olive;">(</span><span style="color: Blue;">shmPtr</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<h2>存放在共享内存中的数据结构</h2>
<p>当保存数据到共享内存中时需要留意，参考如下结构：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">commonData</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">sharedInt</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; </span><span class="hl-types">float</span><span style="color: Gray;">&nbsp; </span><span style="color: Blue;">sharedFloat</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; </span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">name</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Blue;">Struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">CommonData</span><span style="color: Gray;">* </span><span style="color: Blue;">next</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<p>进程A把数据写入共享内存：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">//Attach shared memory</span></li>
<li><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">commonData</span><span style="color: Gray;">* </span><span style="color: Blue;">dp</span><span style="color: Gray;"> =</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">commonData</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">shmat</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">sharedInt</span><span style="color: Gray;"> = </span><span style="color: Maroon;">5</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">.</span></li>
<li><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">name</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">char</span><span style="color: Gray;"> </span><span style="color: Olive;">[</span><span style="color: Maroon;">20</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">strcpy</span><span style="color: Olive;">(</span><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">name</span><span style="color: Gray;">,</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">My Name</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">next</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">commonData</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li></ol></div>
<p>稍后，进程B把数据读出：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">commonData</span><span style="color: Gray;">* </span><span style="color: Blue;">dp</span><span style="color: Gray;"> =</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">commonData</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">shmat</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//count = 5;</span></li>
<li><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">count</span><span style="color: Gray;"> = </span><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">sharedInt</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//problem</span></li>
<li><span style="color: Blue;">printf</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">name = [%s]</span><span style="color: Navy;">\</span><span style="color: Red;">n</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">,</span><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">name</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">dp</span><span style="color: Gray;"> = </span><span style="color: Blue;">dp</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">next</span><span style="color: Gray;">;&nbsp; </span><span style="color: #ffa500;">//problem</span></li></ol></div>
<p>结构 <code>commonData</code> 的成员 <code>name</code> 和指向下一个结构的 <code>next</code> 所指向的内存分别从进程A的地址空间中的堆上分配，显然 name 和 next 指向的内存也只有进程A可以访问。当进程B访问 <code>dp-&gt;name</code> 或者 <code>dp-&gt;next</code> 时候，由于它在访问自己地址空间以外的内存空间，所以这将是非法操作(memory violation)，它无法正确得到 <code>name</code>和 <code>next</code> 所指向的内存。因此，所有的共享内存中的指针必须同样指向共享内存中的地址。（这也是为什么包含虚函数继承的C++类对象不能放到共享内存中的原因——这是另外一个话题。注：因为虚函数的具体实现可能会在其他的内存空间中）由于这些条件限制，放入共享内存中的结构应该简单简单。（注：我觉得最好避免使用指针）</p>
<h2>共享内存中的STL容器</h2>
<p>想像一下把STL容器，例如map, vector, list等等，放入共享内存中，IPC一旦有了这些强大的通用数据结构做辅助，无疑进程间通信的能力一下子强大了很多。我们没必要再为共享内存设计其他额外的数据结构，另外，STL的高度可扩展性将为IPC所驱使。STL容器被良好的封装，默认情况下有它们自己的内存管理方案。当一个元素被插入到一个STL列表(list)中时，列表容器自动为其分配内存，保存数据。考虑到要将STL容器放到共享内存中，而容器却自己在堆上分配内存。一个最笨拙的办法是在堆上构造STL容器，然后把容器复制到共享内存，并且确保所有容器的内部分配的内存指向共享内存中的相应区域，这基本是个不可能完成的任务。例如下边进程A所做的事情：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">//Attach to shared memory</span></li>
<li><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">rp</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">shmat</span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//Construct the vector in shared</span></li>
<li><span style="color: #ffa500;">//memory using placement new</span></li>
<li><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;* </span><span style="color: Blue;">vpInA</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Olive;">(</span><span style="color: Blue;">rp</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;*;</span></li>
<li><span style="color: #ffa500;">//The vector is allocating internal data</span></li>
<li><span style="color: #ffa500;">//from the heap in process A's address</span></li>
<li><span style="color: #ffa500;">//space to hold the integer value</span></li>
<li><span style="color: Olive;">(</span><span style="color: Gray;">*</span><span style="color: Blue;">vpInA</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Maroon;">22</span><span style="color: Gray;">;</span></li></ol></div>
<p>然后进程B希望从共享内存中取出数据：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;* </span><span style="color: Blue;">vpInB</span><span style="color: Gray;"> =</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;*</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmat</span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//problem - the vector contains internal </span></li>
<li><span style="color: #ffa500;">//pointers allocated in process A's address </span></li>
<li><span style="color: #ffa500;">//space and are invalid here </span></li>
<li><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;"> = *</span><span style="color: Olive;">(</span><span style="color: Blue;">vpInB</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li></ol></div>
<h2>重用STL allocator</h2>
<p>进一步考察STL容器，我们发现它的模板定义中有第二个默认参数，也就是allocator 类，该类实际是一个内存分配模型。默认的allocator是从堆上分配内存（注：这就是STL容器的默认表现，我们甚至可以改造它从一个网络数据库中分配空间，保存数据）。下边是 vector 类的一部分定义：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">, </span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">A</span><span style="color: Gray;"> = </span><span style="color: Blue;">allocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt; &gt;</span></li>
<li><span style="color: Gray;">&nbsp; </span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">vector</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">//other stuff</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<p>考虑如下声明：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">//User supplied allocator myAlloc</span></li>
<li><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">,</span><span style="color: Blue;">myAlloc</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt; &gt; </span><span style="color: Blue;">alocV</span><span style="color: Gray;">;</span></li></ol></div>
<p>假设 <code>myAlloc&lt;int&gt;</code> 从共享内存上分配内存，则 <code>alocV</code> 将完全在共享内存上被构造，所以进程A可以如下：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">//Attach to shared memory</span></li>
<li><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">rp</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">shmat</span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//Construct the vector in shared memory</span></li>
<li><span style="color: #ffa500;">//using placement new</span></li>
<li><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;* </span><span style="color: Blue;">vpInA</span><span style="color: Gray;"> =</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Green;">new</span><span style="color: Olive;">(</span><span style="color: Blue;">rp</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">,</span><span style="color: Blue;">myAlloc</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt; &gt;*;</span></li>
<li><span style="color: #ffa500;">//The vector uses myAlloc&lt;int&gt; to allocate</span></li>
<li><span style="color: #ffa500;">//memory for its internal data structure</span></li>
<li><span style="color: #ffa500;">//from shared memory</span></li>
<li><span style="color: Olive;">(</span><span style="color: Gray;">*</span><span style="color: Blue;">v</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Maroon;">22</span><span style="color: Gray;">;</span></li></ol></div>
<p>进程B可以如下读出数据：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt;* </span><span style="color: Blue;">vpInB</span><span style="color: Gray;"> =</span></li>
<li><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">,</span><span style="color: Blue;">myAlloc</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt; &gt;*</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmat</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">shmId</span><span style="color: Gray;">,</span><span class="hl-prepro">NULL</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//Okay since all of the vector is</span></li>
<li><span style="color: #ffa500;">//in shared memory</span></li>
<li><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;"> = *</span><span style="color: Olive;">(</span><span style="color: Blue;">vpInB</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li></ol></div>
<p>所有附着在共享内存上的进程都可以安全的使用该vector。在这个例子中，该类的所有内存都在共享内存上分配，同时可以被其他的进程访问。只要提供一个用户自定义的allocator，任何STL容器都可以安全的放置到共享内存上。</p>
<h2>一个基于共享内存的STL Allocator</h2>
<p>清单 shared_allocator.hh 是一个STL Allocator的实现，<code>SharedAllocator</code> 是一个模板类。而 <code>Pool</code> 类完成共享内存的分配与回收。</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erera.net/wordpress/wp-content/plugins/coolcode/coolcode.php?p=299&amp;download=shared_allocator.hh">shared_allocator.hh</a></div><div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;</span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Pool</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">pool_</span><span style="color: Gray;">;&nbsp; &nbsp; </span><span style="color: #ffa500;">// pool of elements of sizeof(T)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;"> </span><span style="color: Blue;">value_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">unsigned</span><span style="color: Gray;"> </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp; </span><span style="color: Blue;">size_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">ptrdiff_t</span><span style="color: Gray;"> </span><span style="color: Blue;">difference_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">* </span><span style="color: Blue;">pointer</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">* </span><span style="color: Blue;">const_pointer</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">reference</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">const_reference</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">address</span><span style="color: Olive;">(</span><span style="color: Blue;">reference</span><span style="color: Gray;"> </span><span style="color: Blue;">r</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> &amp;</span><span style="color: Blue;">r</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">const_pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">address</span><span style="color: Olive;">(</span><span style="color: Blue;">const_reference</span><span style="color: Gray;"> </span><span style="color: Blue;">r</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Green;">return</span><span style="color: Gray;"> &amp;</span><span style="color: Blue;">r</span><span style="color: Gray;">;</span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">SharedAllocator</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;">:</span><span style="color: Blue;">pool_</span><span style="color: Olive;">(</span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">))</span><span style="color: Gray;"> </span><span style="color: Olive;">{}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">SharedAllocator</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt;&amp; </span><span style="color: Blue;">t</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">pool_</span><span style="color: Olive;">(</span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">))</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; ~</span><span style="color: Blue;">SharedAllocator</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// space for n Ts</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">allocate</span><span style="color: Olive;">(</span><span style="color: Blue;">size_t</span><span style="color: Gray;"> </span><span style="color: Blue;">n</span><span style="color: Gray;">, </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">hint</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Olive;">(</span><span style="color: Green;">static_cast</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">pointer</span><span style="color: Gray;">&gt; </span><span style="color: Olive;">(</span><span style="color: Blue;">pool_</span><span style="color: Gray;">.</span><span style="color: Blue;">alloc</span><span style="color: Olive;">(</span><span style="color: Blue;">n</span><span style="color: Olive;">)))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// deallocate n Ts, don't destroy</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">deallocate</span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Gray;">,</span><span style="color: Blue;">size_type</span><span style="color: Gray;"> </span><span style="color: Blue;">n</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">pool_</span><span style="color: Gray;">.</span><span style="color: Blue;">free</span><span style="color: Olive;">((</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">p</span><span style="color: Gray;">,</span><span style="color: Blue;">n</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// initialize *p by val</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">construct</span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Gray;">, </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">val</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Green;">new</span><span style="color: Olive;">(</span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Olive;">(</span><span style="color: Blue;">val</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// destroy *p but don't deallocate</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">destroy</span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Gray;">-&gt;~</span><span style="color: Blue;">T</span><span style="color: Olive;">()</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_type</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">max_size</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">pool_</span><span style="color: Gray;">.</span><span style="color: Blue;">maxSize</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt;&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// in effect: typedef SharedAllocator&lt;U&gt; other</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">rebind</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">other</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;</span><span class="hl-types">bool</span><span style="color: Gray;"> </span><span style="color: Green;">operator</span><span style="color: Gray;">==</span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;&amp; </span><span style="color: Blue;">a</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;&amp; </span><span style="color: Blue;">b</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Olive;">(</span><span style="color: Blue;">a</span><span style="color: Gray;">.</span><span style="color: Blue;">pool_</span><span style="color: Gray;"> == </span><span style="color: Blue;">b</span><span style="color: Gray;">.</span><span style="color: Blue;">pool_</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;</span><span class="hl-types">bool</span><span style="color: Gray;"> </span><span style="color: Green;">operator</span><span style="color: Gray;">!=</span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;&amp; </span><span style="color: Blue;">a</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;&amp; </span><span style="color: Blue;">b</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Olive;">(</span><span style="color: Blue;">a</span><span style="color: Gray;">.</span><span style="color: Blue;">pool_</span><span style="color: Gray;"> == </span><span style="color: Blue;">b</span><span style="color: Gray;">.</span><span style="color: Blue;">pool_</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>清单pool.hh是 <code>Pool</code> 类定义，其中静态成员<code>shm_</code> 是类型 <code>shmPool</code>，保证每个进程只有唯一的一个<code>shmPool</code> 实例。<code>shmPool</code> ctor 创建并附着所需大小的内存到共享内存上。共享内存的参数，比如 键值、段数目、段大小，都通过环境变量传递给 <code>shmPool</code> ctor。成员 <code>segs_</code> 是共享段的数目，<code>segSize_</code>是每个共享段的大小，成员<code>path_</code>和<code>key_</code> 用来创建唯一的 <code>ipckey</code>。<code>shmPool</code> 为每个共享段创建一个信号量(semaphore)用于同步。<code>shmPool</code> 还在为每个共享段构造了一个 <code>Chunk</code> 类，一个 <code>Chunk</code>代表一个共享段。每个共享段的标识是<code>shmId_</code>， 信号量 <code>semId_</code>控制该段的访问许可，一个指向 <code>Link</code> 结构的指针表明 <code>Chunk</code>类的剩余列表。</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erera.net/wordpress/wp-content/plugins/coolcode/coolcode.php?p=299&amp;download=pool.hh">pool.hh</a></div><div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">Pool</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmPool</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Container</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">containerMap</span><span style="color: Gray;">* </span><span style="color: Blue;">cont</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Chunk</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Chunk</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Chunk</span><span style="color: Olive;">(</span><span style="color: Blue;">Chunk</span><span style="color: Gray;">&amp;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~</span><span style="color: Blue;">Chunk</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">alloc</span><span style="color: Olive;">(</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">free</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">p</span><span style="color: Gray;">,</span><span style="color: Blue;">size_t</span><span style="color: Gray;"> </span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmId_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">semId_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">lock_</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">key_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">path_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Chunk</span><span style="color: Gray;">** </span><span style="color: Blue;">chunks_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">segs_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">segSize_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">contPtr_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">contSemId_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">shmPool</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~</span><span style="color: Blue;">shmPool</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">maxSize</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">alloc</span><span style="color: Olive;">(</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">free</span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">p</span><span style="color: Gray;">, </span><span style="color: Blue;">size_t</span><span style="color: Gray;"> </span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmPool</span><span style="color: Gray;">::</span><span style="color: Blue;">lockContainer</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">unLockContainer</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">containerMap</span><span style="color: Gray;">* </span><span style="color: Blue;">getContainer</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmPool</span><span style="color: Gray;">::</span><span style="color: Blue;">setContainer</span><span style="color: Olive;">(</span><span style="color: Blue;">containerMap</span><span style="color: Gray;">* </span><span style="color: Blue;">container</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">static</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">shmPool</span><span style="color: Gray;"> </span><span style="color: Blue;">shm_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">elemSize_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Pool</span><span style="color: Olive;">(</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">elemSize</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; ~</span><span style="color: Blue;">Pool</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">maxSize</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">alloc</span><span style="color: Olive;">(</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">free</span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">* </span><span style="color: Blue;">p</span><span style="color: Gray;">, </span><span style="color: Blue;">size_t</span><span style="color: Gray;"> </span><span style="color: Blue;">size</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">lockContainer</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">unLockContainer</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">containerMap</span><span style="color: Gray;">* </span><span style="color: Blue;">getContainer</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">setContainer</span><span style="color: Olive;">(</span><span style="color: Blue;">containerMap</span><span style="color: Gray;">* </span><span style="color: Blue;">container</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">inline</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">bool</span><span style="color: Gray;"> </span><span style="color: Green;">operator</span><span style="color: Gray;">==</span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">Pool</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">a</span><span style="color: Gray;">,</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">Pool</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">b</span><span style="color: Olive;">)</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Olive;">(</span><span style="color: Blue;">a</span><span style="color: Gray;">.</span><span style="color: Blue;">compare</span><span style="color: Olive;">(</span><span style="color: Blue;">b</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<h2>把STL容器放入共享内存</h2>
<p>假设进程A在共享内存中放入了数个容器，进程B如何找到这些容器呢？一个方法就是进程A把容器放在共享内存中的确定地址上（fixed offsets），则进程B可以从该已知地址上获取容器。另外一个改进点的办法是，进程A先在共享内存某块确定地址上放置一个map容器，然后进程A再创建其他容器，然后给其取个名字和地址一并保存到这个map容器里。进程B知道如何获取该保存了地址映射的map容器，然后同样再根据名字取得其他容器的地址。清单container_factory.hh是一个容器工厂类。类<code>Pool</code>的方法<code>setContainer</code>把map容器放置在一个已知地址上，方法<code>getContainer</code>可以重新获取这个map。该工厂的方法用来在共享内存中创建、获取和删除容器。当然，传递给容器工厂的容器需要以<code>SharedAllocator</code>作为allocator。</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erera.net/wordpress/wp-content/plugins/coolcode/coolcode.php?p=299&amp;download=container_factory.hh">container_factory.hh</a></div><div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">struct</span><span style="color: Gray;"> </span><span style="color: Blue;">keyComp</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span class="hl-types">bool</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">operator</span><span style="color: Olive;">()(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">key1</span><span style="color: Gray;">,</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">key2</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Olive;">(</span><span style="color: Blue;">strcmp</span><span style="color: Olive;">(</span><span style="color: Blue;">key1</span><span style="color: Gray;">,</span><span style="color: Blue;">key2</span><span style="color: Olive;">)</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">containerMap</span><span style="color: Gray;">: </span><span style="color: Green;">public</span><span style="color: Gray;"> </span><span style="color: Blue;">map</span><span style="color: Gray;">&lt;</span><span class="hl-types">char</span><span style="color: Gray;">*,</span><span class="hl-types">void</span><span style="color: Gray;">*,</span><span style="color: Blue;">keyComp</span><span style="color: Gray;">,</span><span style="color: Blue;">SharedAllocator</span><span style="color: Gray;">&lt;</span><span class="hl-types">char</span><span style="color: Gray;">* &gt; &gt; </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">containerFactory</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">containerFactory</span><span style="color: Olive;">()</span><span style="color: Gray;">:</span><span style="color: Blue;">pool_</span><span style="color: Olive;">(</span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">containerMap</span><span style="color: Olive;">)){}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; ~</span><span style="color: Blue;">containerFactory</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Container</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">createContainer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">key</span><span style="color: Gray;">,</span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">c</span><span style="color: Gray;">=</span><span class="hl-prepro">NULL</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Container</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">getContainer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">key</span><span style="color: Gray;">,</span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">c</span><span style="color: Gray;">=</span><span class="hl-prepro">NULL</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">template</span><span style="color: Gray;">&lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Container</span><span style="color: Gray;">&gt; </span><span class="hl-types">int</span><span style="color: Gray;"> </span><span style="color: Blue;">removeContainer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span class="hl-types">char</span><span style="color: Gray;">* </span><span style="color: Blue;">key</span><span style="color: Gray;">,</span><span style="color: Blue;">Container</span><span style="color: Gray;">* </span><span style="color: Blue;">c</span><span style="color: Gray;">=</span><span class="hl-prepro">NULL</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">private</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Pool</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">pool_</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">lock_</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">unlock_</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<h2>结论</h2>
<p>本文描述的方案可以在共享内存中创建STL容器，其中的一个缺陷是，在分配共享内存之前，应该保证共享内存的总大小(<code>segs_* segSize_</code>)大于你要保存STL容器的最大长度，因为一旦类<code>Pool</code> 超出了共享内存的，该类无法再分配新的共享内存。</p>
<p>完整的源代码可以从这里下载：www.cuj.com/code</p>
<h2>参考文献</h2>
<ul>
<li>Bjarne Stroustrup. The C++ Programming Language, Third Edition (Addison-Wesley, 1997).</li>
<li>Matthew H. Austern. Generic Programming and the STL: Using and<br />
Extending the C++ Standard Template Library (Addison-Wesley, 1999).
</li>
</ul>
<h2>关于作者</h2>
<p>Grum Ketema has Masters degrees in Electrical Engineering and Computer Science. With 17 years of experience in software development, he has been using C since 1985, C++ since 1988, and Java since 1997. He has worked at AT&#038;T Bell Labs, TASC, Massachusetts Institute of Technology, SWIFT, BEA Systems, and Northrop. </p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/creating-stl-containers-in-shared-memory.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>STL容器放入共享内存</title>
		<link>http://erera.net/blog/stl-alloc.html</link>
		<comments>http://erera.net/blog/stl-alloc.html#comments</comments>
		<pubDate>Sun, 01 Feb 2009 19:17:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[开发学习]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://erera.net/?p=294</guid>
		<description><![CDATA[STL可以说是C++的重要的组成部分，它提供了一系列方便使用的容器，可以供我们存放数据，节省了很多开发时间。不过如果打算在多个进程之间共享一个STL容器，却常常会遭遇一些困难。比如你正在使用一个map，一般的IPC方法，可能下意识的你就会选择使用共享内存，如果可以把这个map放入一块共享内存供多个进程操作，那该多方便呢。然而问题却没这么简单，由于STL帮我们完美的封装好了map的内部方法，包括内存分配方案，这也导致了我们没法把map直接简单的用placement new放置到已知的共享内存上。
要完成这个任务就需要我们自己实现一个基于共享内存的allocator，替换map默认的allocator，在这个allocator中实现map的内存分配方案。关于allocator的讲解可以看侯捷的《STL源码剖析》这本书，写一个简单的allocator直接套下边的模板就可以了，主要实现的是这几个函数：

 max_size() 容器的最大容量
 allocate(num) 为num个元素分配内存
 construct(p) 将p所指的元素初始化
 destroy(p) 销毁p所指向的元素
 deallocate(p, num)  收回p所指的num个空间


&#19979;&#36733;: myalloc.hh#include &#60;limits&#62;
#include &#60;iostream&#62;
&#160;
namespace&#160;MyLib {
&#160;&#160; template &#60;class&#160;T&#62;
&#160;&#160; class&#160;MyAlloc {
&#160; &#160;&#160; public:
&#160; &#160; &#160;&#160; // type definitions
&#160; &#160; &#160;&#160; typedef&#160;T&#160; &#160; &#160; &#160; value_type;
&#160; &#160; &#160;&#160; typedef&#160;T*&#160; &#160; &#160;&#160; pointer;
&#160; &#160; &#160;&#160; typedef&#160;const T* const_pointer;
&#160; &#160; &#160;&#160; typedef&#160;T&#38;&#160; &#160; &#160;&#160; reference;
&#160; &#160; &#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sgi.com/tech/stl" class="liexternal">STL</a>可以说是C++的重要的组成部分，它提供了一系列方便使用的容器，可以供我们存放数据，节省了很多开发时间。不过如果打算在多个进程之间共享一个STL容器，却常常会遭遇一些困难。比如你正在使用一个map，一般的IPC方法，可能下意识的你就会选择使用共享内存，如果可以把这个map放入一块共享内存供多个进程操作，那该多方便呢。然而问题却没这么简单，由于STL帮我们完美的封装好了map的内部方法，包括内存分配方案，这也导致了我们没法把map直接简单的用placement new放置到已知的共享内存上。</p>
<p>要完成这个任务就需要我们自己实现一个基于共享内存的allocator，替换map默认的allocator，在这个allocator中实现map的内存分配方案。关于allocator的讲解可以看侯捷的《<a href="http://www.china-pub.com/6384" class="liexternal">STL源码剖析</a>》这本书，写一个简单的allocator直接套下边的模板就可以了，主要实现的是这几个函数：</p>
<ul>
<li> <code>max_size()</code> 容器的最大容量</li>
<li> <code>allocate(num)</code> 为num个元素分配内存</li>
<li> <code>construct(p)</code> 将p所指的元素初始化</li>
<li> <code>destroy(p)</code> 销毁p所指向的元素</li>
<li> <code>deallocate(p, num)</code>  收回p所指的num个空间</li>
</ul>
<p><span id="more-294"></span></p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erera.net/wordpress/wp-content/plugins/coolcode/coolcode.php?p=294&amp;download=myalloc.hh">myalloc.hh</a></div><div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-prepro">#include </span><span style="color: #8b0000;">&lt;</span><span style="color: Red;">limits</span><span style="color: #8b0000;">&gt;</span><span class="hl-prepro"></span></li>
<li><span class="hl-prepro">#include </span><span style="color: #8b0000;">&lt;</span><span style="color: Red;">iostream</span><span style="color: #8b0000;">&gt;</span><span class="hl-prepro"></span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span class="hl-types">namespace</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyLib</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">template</span><span style="color: Gray;"> &lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&gt;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Green;">public</span><span style="color: Gray;">:</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// type definitions</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">value_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">*&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">* </span><span style="color: Blue;">const_pointer</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T</span><span style="color: Gray;">&amp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">reference</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">const_reference</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">size_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">ptrdiff_t</span><span style="color: Gray;"> </span><span style="color: Blue;">difference_type</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// rebind allocator to type U</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">template</span><span style="color: Gray;"> &lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">struct</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">rebind</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">typedef</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">other</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// return address of values</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">address</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">reference</span><span style="color: Gray;"> </span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;"> &amp;</span><span style="color: Blue;">value</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">const_pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">address</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">const_reference</span><span style="color: Gray;"> </span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;"> &amp;</span><span style="color: Blue;">value</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-mlcomment">/* constructors and destructor</span></li>
<li><span class="hl-mlcomment">&nbsp; &nbsp; &nbsp; &nbsp; * - nothing to do because the allocator has no state</span></li>
<li><span class="hl-mlcomment">&nbsp; &nbsp; &nbsp; &nbsp; */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">MyAlloc</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">MyAlloc</span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&amp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">template</span><span style="color: Gray;"> &lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">U</span><span style="color: Gray;">&gt;&amp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; ~</span><span style="color: Blue;">MyAlloc</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// return maximum number of elements that can be allocated</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">size_type</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">max_size</span><span style="color: Gray;"> </span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">numeric_limits</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">size_t</span><span style="color: Gray;">&gt;::</span><span style="color: Blue;">max</span><span style="color: Olive;">()</span><span style="color: Gray;"> / </span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// allocate but don't initialize num elements of type T</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">allocate</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">size_type</span><span style="color: Gray;"> </span><span style="color: Blue;">num</span><span style="color: Gray;">, </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span class="hl-types">void</span><span style="color: Gray;">* = </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// print message and allocate memory with global new</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">cerr</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">allocate </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Blue;">num</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> element(s)</span><span style="color: #8b0000;">&quot;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> of size </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">)</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">endl</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">pointer</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">ret</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Olive;">)(</span><span style="color: Gray;">::</span><span style="color: Green;">operator</span><span style="color: Gray;"> </span><span style="color: Green;">new</span><span style="color: Olive;">(</span><span style="color: Blue;">num</span><span style="color: Gray;">*</span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">)))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">cerr</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> allocated at: </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">ret</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">endl</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">ret</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// initialize elements of allocated storage p with value value</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">construct</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Gray;">, </span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">T</span><span style="color: Gray;">&amp; </span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// initialize memory with placement new</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">new</span><span style="color: Olive;">((</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Blue;">T</span><span style="color: Olive;">(</span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// destroy elements of initialized storage p</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">destroy</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// destroy objects by calling their destructor</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">p</span><span style="color: Gray;">-&gt;~</span><span style="color: Blue;">T</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// deallocate storage p of deleted elements</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="hl-types">void</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">deallocate</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">pointer</span><span style="color: Gray;"> </span><span style="color: Blue;">p</span><span style="color: Gray;">, </span><span style="color: Blue;">size_type</span><span style="color: Gray;"> </span><span style="color: Blue;">num</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #ffa500;">// print message and deallocate memory with global delete</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">cerr</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">deallocate </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Blue;">num</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> element(s)</span><span style="color: #8b0000;">&quot;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> of size </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Green;">sizeof</span><span style="color: Olive;">(</span><span style="color: Blue;">T</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &lt;&lt; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> at: </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Olive;">(</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">p</span><span style="color: Gray;"> &lt;&lt; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">endl</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; ::</span><span style="color: Green;">operator</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">delete</span><span style="color: Olive;">((</span><span class="hl-types">void</span><span style="color: Gray;">*</span><span style="color: Olive;">)</span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: #ffa500;">// return that all specializations of this allocator are interchangeable</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">template</span><span style="color: Gray;"> &lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T1</span><span style="color: Gray;">, </span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">T2</span><span style="color: Gray;">&gt;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">bool</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">operator</span><span style="color: Gray;">== </span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T1</span><span style="color: Gray;">&gt;&amp;,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T2</span><span style="color: Gray;">&gt;&amp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">true</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">template</span><span style="color: Gray;"> &lt;</span><span class="hl-types">class</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">T1</span><span style="color: Gray;">, </span><span class="hl-types">class</span><span style="color: Gray;"> </span><span style="color: Blue;">T2</span><span style="color: Gray;">&gt;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span class="hl-types">bool</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">operator</span><span style="color: Gray;">!= </span><span style="color: Olive;">(</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T1</span><span style="color: Gray;">&gt;&amp;,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-types">const</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">T2</span><span style="color: Gray;">&gt;&amp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">throw</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>如果要使用这个allocator的话，可以这样：</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-prepro">#include </span><span style="color: #8b0000;">&lt;</span><span style="color: Red;">vector</span><span style="color: #8b0000;">&gt;</span><span class="hl-prepro"></span></li>
<li><span class="hl-prepro">#include </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">myalloc.hh</span><span style="color: #8b0000;">&quot;</span><span class="hl-prepro"></span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span class="hl-types">int</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">main</span><span style="color: Olive;">()</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">// create a vector, using MyAlloc&lt;&gt; as allocator</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">vector</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">,</span><span style="color: Blue;">MyLib</span><span style="color: Gray;">::</span><span style="color: Blue;">MyAlloc</span><span style="color: Gray;">&lt;</span><span class="hl-types">int</span><span style="color: Gray;">&gt; &gt; </span><span style="color: Blue;">v</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">// insert elements</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">// - causes reallocations</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">v</span><span style="color: Gray;">.</span><span style="color: Blue;">push_back</span><span style="color: Olive;">(</span><span style="color: Maroon;">42</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>不过写出这样一个简单的vector内存分配器是很容易，不过如果要针对map或者hash_map写一份高效鲁棒的内存分配器却也不是一件容易的事情。一个想法就是在共享内存上划分出内存池，自己对这块内存池进行维护，并且还得考虑进程同步问题。然而，一件幸运的事情是，在<a href="http://www.boost.org" class="liexternal">boost</a>项目第1.35个版本之后，已经增加了一个叫做<code>boost::interprocess</code>的库，其中包含了关于多线程和多进程的很多有用的辅助类库，当中也有为STL容器所写的allocator，这里有一系列非常棒的<a href="http://www.boost.org/doc/libs/1_37_0/doc/html/interprocess/quick_guide.html" class="liexternal">示例程序</a>。</p>
<p>不过其中有一个注意点，由于allocator是以类的形式提供的，所以当你在使用STL容器的时候，你需要保证allocator的实例没有被销毁，例如下边的函数希望产生<code>mymap</code>这个指针供其他函数使用，结果将是错误的。事实上，一旦该函数运行结束，mymap所指向的内存地址将会失效。</p>
<div class="hl-surround"><ol class="hl-main ln-hide" title="Double click to show line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span class="hl-types">int</span><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">KeyType</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span class="hl-types">float</span><span style="color: Gray;">&nbsp; </span><span style="color: Blue;">MappedType</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">pair</span><span style="color: Gray;">&lt;</span><span class="hl-types">const</span><span style="color: Gray;"> </span><span style="color: Blue;">KeyType</span><span style="color: Gray;">, </span><span style="color: Blue;">MappedType</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ValueType</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span style="color: Blue;">allocator</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">ValueType</span><span style="color: Gray;">, </span><span style="color: Blue;">managed_shared_memory</span><span style="color: Gray;">::</span><span style="color: Blue;">segment_manager</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ShmemAllocator</span><span style="color: Gray;">;</span></li>
<li><span class="hl-types">typedef</span><span style="color: Gray;"> </span><span style="color: Blue;">map</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">KeyType</span><span style="color: Gray;">, </span><span style="color: Blue;">MappedType</span><span style="color: Gray;">, </span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">less</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">KeyType</span><span style="color: Gray;">&gt;, </span><span style="color: Blue;">ShmemAllocator</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">MyMap</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">MyMap</span><span style="color: Gray;">* </span><span style="color: Blue;">get_ptr</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">using</span><span style="color: Gray;">&nbsp;</span><span class="hl-types">namespace</span><span style="color: Gray;"> </span><span style="color: Blue;">boost</span><span style="color: Gray;">::</span><span style="color: Blue;">interprocess</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">managed_shared_memory</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">segment</span><span style="color: Olive;">(</span><span style="color: Blue;">create_only</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">MySharedMemory</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Maroon;">65536</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">ShmemAllocator</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">alloc_inst</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">segment</span><span style="color: Gray;">.</span><span style="color: Blue;">get_segment_manager</span><span style="color: Olive;">())</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">//如果你希望把mymap当作参数传递到别的函数中去处理，请保证此时alloc_inst这个实例是存在的。</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">MyMap</span><span style="color: Gray;"> *</span><span style="color: Blue;">mymap</span><span style="color: Gray;"> = </span><span style="color: Blue;">segment</span><span style="color: Gray;">.</span><span style="color: Blue;">construct</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">MyMap</span><span style="color: Gray;">&gt;</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">MyMap</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)(</span><span style="color: Blue;">std</span><span style="color: Gray;">::</span><span style="color: Blue;">less</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">KeyType</span><span style="color: Gray;">&gt;</span><span style="color: Olive;">()</span><span style="color: Gray;">,</span><span style="color: Blue;">alloc_inst</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">mymap</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>另外由 <code>managed_shared_memory</code> 创建的共享内存默认属性是 <code>600</code>。总之，结合了STL和boost库，把STL容器放入共享内存中供多进程使用，就变成了一件非常容易而且愉快的事情。</p>
]]></content:encoded>
			<wfw:commentRss>http://erera.net/blog/stl-alloc.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.900 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-10 05:25:07 -->
<!-- Compression = gzip -->