<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6431648168352285436</id><updated>2011-12-19T23:28:14.444+08:00</updated><category term='linux kernel'/><category term='linux install'/><category term='21 grams'/><category term='life'/><title type='text'>一碗阳春面</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-974333943974903731</id><published>2011-12-19T22:13:00.011+08:00</published><updated>2011-12-19T23:28:14.454+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>一封无法投递的信</title><content type='html'>&lt;object width='320' height='50'&gt;&lt;param name='movie' value='http://www.onmvoice.com/player/player.swf?a=77185&amp;ap=0&amp;color=default'&gt;&lt;/param&gt;&lt;param name='allowFullScreen' value='true'&gt;&lt;/param&gt;&lt;param name='allowscriptaccess' value='always'&gt;&lt;/param&gt;&lt;param name='menu' value='false'&gt;&lt;/param&gt;&lt;embed src='http://www.onmvoice.com/player/player.swf?a=77185&amp;ap=0&amp;color=default' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' menu='false' loop='true' width='320' height='50'&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;    昨晚听高楠说李国强出车祸去世了，心情无法平静。毕竟是从孩提时代一起长大的，曾经一起上过山、&lt;br /&gt;爬过树、下过河，一起哭过笑过。&lt;br /&gt;&lt;br /&gt;    小强1980年生，比我小2岁，他两个姐都比我大。他不是学习的料，小学毕业就下来干活了，修车很厉&lt;br /&gt;害，这人真是各好一路。由于下来的早，就和村里另外几个不上学的半大小子混，学会偷东西了。我的piaji&lt;br /&gt;和流流不敢放屋里，怕被爸看见，就藏在外面，被他发现偷去了，后来他托大龙给我送回来很多。后来我上&lt;br /&gt;高中阶段来往就不多了，他犯的事就大了，公安局总过来抓村里他们几个。有一次警察先去抓主犯，路过他&lt;br /&gt;家，大冬天的他穿着衬裤跑大龙家去了，等车再回来就没抓着他。&lt;br /&gt;&lt;br /&gt;    印象比较深刻的是1989年夏天，我12岁，他10岁，我们两个一起去河东边的杨树林里找杨拉罐。那天他&lt;br /&gt;来找我，我本来就喜欢上山下河，跟妈说了不少好话，说去采蘑菇，一会就回来吃午饭，妈终于同意了。我&lt;br /&gt;们像脱缰的野马，那小树林里的杨拉罐可多了，河水不深，小树不大，只是那杨拉子专门在树尖上吐丝，所&lt;br /&gt;以我们直接就把人家树尖给折了。由于村里我们几个喜欢杨拉罐的以前去过，人家肯定发现树都被折了，就&lt;br /&gt;注意了。我们正找着，突然那家有人大喊一声，把我们两个吓的撒腿就跑，专门往荒草里跑。歇了一会俩人&lt;br /&gt;都觉得还是上山过瘾，就一起去村后的磨盘山了。毕竟人小，不敢往深山里走，就在山外面，一个蘑菇也没&lt;br /&gt;有。走着走着我突然听见地下有“吱吱”的声音，低头一看，一条比大人的大拇指还要粗的黑色的蛇正往另外&lt;br /&gt;一边爬呢！吓得我一边叫一边往路上跑，说小强快出去，这附近有大蛇。我们跑到了路上，一起往蛇出现的&lt;br /&gt;方向扔了几块石头，心里很害怕，就商量回家。其实那蛇就是土球子，没有毒也不主动咬人，肯定它先看见&lt;br /&gt;我了就跑了。正往回走，一队部队的人去山里打靶，一个班能有10多个人，就走着去。我们一下就高兴坏了，&lt;br /&gt;之前我们就喜欢和半大小子去打靶的地方挖子弹头拣子弹壳。就跟着部队的人进山了，他们说你们到时候可&lt;br /&gt;不能乱跑，就老实的坐那，否则不让看，我们说一定听话。我们俩就坐那看他们打靶，过了一会又来了村里&lt;br /&gt;几个半大小子。就这样不知不觉地一整天就过去了，下午的时候发现山脚那边有人大声喊，我听见了还看了&lt;br /&gt;一眼，没在意。部队的人打完靶了我们去拿棍挖了一些子弹头，又拣了很多子弹壳，日头快落下去了，就开&lt;br /&gt;始和别人一起往回走。出了山，我们还不想走大路呢，就喜欢走山路，就一边聊一边顺着水利局水库走，走&lt;br /&gt;到老周家水库那，看到妈背着石头正喊我们俩呢。妈说两家人找你们一下午了，以为你们丢了，你等着你爸&lt;br /&gt;回家收拾你吧，绳儿都准备好了，要绑起来揍。我俩一听吓坏了，赶紧往家走。后来才知道下午冲打靶这边&lt;br /&gt;喊的人就是爸！两家人中午没见到人回家，以为出事了，就开始到处找，爸绕着磨盘山一大圈，一边走一边&lt;br /&gt;喊我们两个，他家人也把附近都翻遍了。我刚一到家爸就要揍我，让大姐姐夫给拉开了，我一看绳子真准备&lt;br /&gt;好了，以前虽然也没少挨揍但没见过绳子，妈说你快跑吧，我撒腿就跑，跑胡同上面的荒地中去了，呆了一&lt;br /&gt;个多小时，天黑了，看到两个男的，隔着有300米远，两个人都冲我这边走，我一看就想起偷小孩的了，就顺&lt;br /&gt;着去干沟的路走，我这一走，其中一个男的就开始迂回，应该是想往我的前面走，附近除了野草就是苞米地，&lt;br /&gt;只有一家人，把我吓坏了，低下腰借着路边野草的掩护又原路跑回去了，然后进了那家的瓜子地，顺着瓜子&lt;br /&gt;地绕了个大圈一口气跑大道上了，吓得不轻，直到现在也不确定那俩人是不是偷小孩的。&lt;br /&gt;&lt;br /&gt;    第二天，他妈领着他来我家了，说小强让谁给打了？就是村里的一个半大小子，得16、7岁了，小强坐&lt;br /&gt;在那的时候一个当兵的掉了一颗完整的子弹，他就拣到了。挖子弹头的时候老盖家的一个半大小子要看看，&lt;br /&gt;小强不让他看，那小子生气了就打了他两下，当时我也没敢说话，因为他们人多，还都比我们大很多，我们&lt;br /&gt;两个也打不过其中一个啊，也就算了。结果一到家小强肯定是和他家人说了，他妈要找那小子家里去，我说&lt;br /&gt;我不能说，要说了他们过后该揍我了，他妈说你怕啥呀去找他家去，我说就别找了，他妈挺生气的就走了。&lt;br /&gt;也不知道后来找没找老盖家，现在想想挺对不起小强的，小孩子的想法毕竟单纯，他也不生我的气，过后照&lt;br /&gt;样一起玩。&lt;br /&gt;&lt;br /&gt;    还有一次我上初中，一天周末他来找我，说去捞鱼，我一听乐坏了，就找个破网一起去了。其实是人家&lt;br /&gt;老周加的鱼池子，人家专门放鱼的地方，当然好捞了，刚捞了5、6条，他家大小子过来了，一边跑一边说&lt;br /&gt;“你们两个是不祸害人呢！” 我以为得挨揍呢，人家一看是一个村的就没在说什么，我们两个就回去了。&lt;br /&gt;&lt;br /&gt;    从很小的时候，过年就在一起玩扑克，和上院的大龙，再加上他二姐或者大龙他姐。上了高中我空闲时&lt;br /&gt;间少了，就周末有时候在地里能见到他。我上大学之后就更少见了，只能暑假寒假见面。有天晚上在公汽上&lt;br /&gt;碰到，还专门到家里聊了很长时间。&lt;br /&gt;&lt;br /&gt;    去大连之后我好几年都没回家，没见过村里任何人。06年8月份我回去，知道他结婚了，生了个儿子。&lt;br /&gt;当时我没工作，没有钱给他。他和媳妇也没弄明白，好像是离过一次后来又复婚了。&lt;br /&gt;&lt;br /&gt;    2007年或者08年的冬天。快过年了天很冷我和高楠、石头在路口等公汽，去街里买东西。一辆车突然停&lt;br /&gt;下来了，让我们上车，我一看是他，就上去了。挺破一辆车，我听说了他和县里黑社会的在一起，倒腾一些&lt;br /&gt;黑车。他说送你们到街口，不敢往里走，黑车没号牌。回来买鞭炮的时候又见到他了，和黑社会的人一起，&lt;br /&gt;我们打声招呼就走了，这也是最后一面。&lt;br /&gt;&lt;br /&gt;    这次丧命也是因为酒后驾车，才32岁，真是可怜，以后连一起喝酒的机会也没了。想想和大龙我们3个从&lt;br /&gt;小总在一起玩。小强走了，大龙在钢铁厂里弄掉一个大拇指头，我最后也很可能也会把命扔在这，不仅感慨&lt;br /&gt;世事无常，对农村的孩子来讲，人生如棋，容不得走错一步。&lt;br /&gt;&lt;br /&gt;    小强虽然有偷东西的毛病，长大之后却没在附近的邻居家偷过，比那些专门偷邻居的毛贼还是强多了，&lt;br /&gt;更比那些明着抢钱的窃国之贼强多了，也比如今那些道貌岸然读20多年书的学贼强多了。中国人对逝者总是&lt;br /&gt;专挑好的说，我要么不写，要写就有血有肉，小强你若有灵不会介意吧？&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-974333943974903731?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/974333943974903731/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/12/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/974333943974903731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/974333943974903731'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/12/blog-post.html' title='一封无法投递的信'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-7579960846531257462</id><published>2011-09-20T22:30:00.001+08:00</published><updated>2011-09-20T22:34:01.042+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Dropbox and MU</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    从2009年下半年开始使用网盘，上传下载了很多数据，很方便。昨天有人问我网盘的事，引发了感触。&lt;br /&gt;&lt;br /&gt;    第一次接触的网盘是 Dropbox，2009年上半年，那时已经是 Windows、Mac、Linux 都跑的很好了，而且&lt;br /&gt;可以实时同步，当一个文件夹用，特别优秀的软件，一见钟情。&lt;br /&gt;&lt;br /&gt;    先进技术必然会阻碍中国的正常发展，因此必须坚决抵制。不久 Dropbox 主页就被墙了，很难下载到。&lt;br /&gt;好在只要下到了装上还能正常用。目前 Windows 只要有 .exe 就能正常安装使用，Linux 下安装会有点小问&lt;br /&gt;题，稍微琢磨一下就能装上了，只要装上了也能正常使用。速度一般是 50KB/S，快的时候能达到 150KB/S，&lt;br /&gt;一直再用。&lt;br /&gt;&lt;br /&gt;    如果想要大容量的就用 MegaUpload，默认免费空间就 200GB，网页简洁清新。上传快还特别方便，可以&lt;br /&gt;直接用浏览器上传，同时开4个IE上传，每个速度都能达到 200KB/S ；有时网速慢，每个进程只能达到&lt;br /&gt;100KB/S ，那就可以开8个IE同时上传；下载可以用它的客户端，也可以用迅雷，在 Linux 下还可以用lftp、&lt;br /&gt;mldonkey 等等下载，速度能达到 250KB/S ，特别方便。数据在MU上的保存时间最少3个月，有人下载就会自&lt;br /&gt;动续期，我的有些资料已经在上面半年多了没人下载，还都在。&lt;br /&gt;&lt;br /&gt;    目前 MU 上传正常，但下载已经被墙了，现在直接通过IP还能下载，下载速度很不稳定，150KB/S 左右。&lt;br /&gt;&lt;br /&gt;    Dropbox + MU 已经很完美了，其它网盘如果不能在容量上有优势，那就是完全多余，比如中国人做的网&lt;br /&gt;盘。有时上传数据给对方，对方又不能上国外网，这时就只有用国内网盘了。国内的 Rayfile、115、gokuai&lt;br /&gt;是主流，我都试过，别说2年前，就现在已经是2011年了，还没有一个能比得上 MU 的；至于 Dropbox 的竞&lt;br /&gt;争者，直到 2011 年上半年还没遇到过好用的，昨天听人说国内也有能用的了，我是不会去试验的，Dropbox&lt;br /&gt;就是我的最爱。&lt;br /&gt;&lt;br /&gt;    爱上 Dropbox + MU 的理由很充分，以下是我2年多的实际体验:&lt;br /&gt;&lt;br /&gt;1. 能保证上传到它们的资料不会无缘无故消失。国内网盘经常毫无迹象的消失。&lt;br /&gt;&lt;br /&gt;2. 上传到它们的 rar 文件从来没出过解压出错的问题。国内网盘可是经常出错。&lt;br /&gt;&lt;br /&gt;3. 有时候网络中心有问题，实验室登录网页每隔15分钟就断网重连一次，如果这时正用IE往115上传东西，&lt;br /&gt;就会出错，只有重传。但如果此时正用 IE 往 MU 上传东西就没有影响，容错相当成功，这时就看出质量了。&lt;br /&gt;&lt;br /&gt;4. MU 上传总速度能达到 800KB/S，国内的都达不到这个速度，gokuai能到700KB/S，但下载有流量限制。&lt;br /&gt;&lt;br /&gt;5. 它们都不限下载次数，随便下。&lt;br /&gt;&lt;br /&gt;6. MU 容量大，有效期长达3个月以上，传上去就不用管了，省心也放心。&lt;br /&gt;&lt;br /&gt;7. 简洁清新，专注于存储，做到了KiSS，Keep it Simple Stupid，利用广告和更高需求的服务赚钱。虽然&lt;br /&gt;功能简单，但稳定、容错好，做到有质量。直到有用户群了在继续投入到其它方面，试着抢抢 gtalk、skype&lt;br /&gt;的用户，对方在即时通讯领域都做的特别好，这个是很难抢的，但即使抢不过去也不会伤筋动骨。国外人做&lt;br /&gt;的东西靠谱，让人放心。国内的则是一开始就大杂烩，好友、站内发送文件什么的很杂，最有用的下载功能&lt;br /&gt;却做的不好，还有的你必须用他们的专用客户端才能下，根本不知道他们想干什么，也不想想能抢过人家QQ&lt;br /&gt;的用户么，一旦抢不过就全盘皆输。&lt;br /&gt;&lt;br /&gt;    一个网盘就能对比出来对技术的态度。国人学习能力一般，能学会别人的 80%，创新能力几乎是0。都得&lt;br /&gt;靠政治力量把国外好东西封锁了自己继续花上2年时间才能模仿出来一个80%的山寨版本。对于已经有成熟技&lt;br /&gt;术的方面很是热衷，有的过后还很有成就感。一次我看片，一个哥们说你这是从***下的吧? 很方便吧，那是&lt;br /&gt;我传上去的。我说是从电驴上拖的。我下那版本质量好多了，他说那个工具是他们小组做的，几个博士领着&lt;br /&gt;几个硕士做带搜索功能的ftp，只限于局域网、断点续传常出问题、很不稳定，还花了一大笔钱。如果我是学&lt;br /&gt;术委员会的人，硕士都毕业吧，博士做这个的全都是负分，比不做的还恶劣。因为verycd那web搜索广域网上&lt;br /&gt;早就做的特别好用了，已经有了成熟稳定的工具，非要在花钱做一个简化的不稳定版，这就是大陆的research，&lt;br /&gt;实际上应该叫做search。做出烂东西还不忘和别人显摆，这么浅薄的人也能成为大陆的researcher，我估计&lt;br /&gt;如果是胡适先生那代人做教授，这样人本科都该多读半年再毕业。&lt;br /&gt;&lt;br /&gt;    有的弟弟说到了迅雷看看、在线看视频。这都不是创新，找本科生就能做了，看看 lftp 源码，或者&lt;br /&gt; Linux 下mount上 Windows NTFS 硬盘，然后直接 $ mplayer 意大利绝景.04.mp4.emule.td &lt;br /&gt;好了，能看了，都是已经有成熟工具的技术了。先 search 一下，没有再说是research，此时能快速创新的&lt;br /&gt;叫做聪明、效率高；已经有的能快速出来产品的那叫熟练、能加班，是worker不是researcher。&lt;br /&gt;&lt;br /&gt;    大陆的教科书和论文也有类似特点。国外的论文不会过多的介绍成熟的东西，创新的东西才是人们关注&lt;br /&gt;的，教科书则尽量细致，把原理说明白，最新的成果则只给引用，不过多介绍喧宾夺主；国内是论文要有页&lt;br /&gt;数限制，废话一堆，原创之处很少很少，看着像教科书；而教科书则高深莫测，把三句话并成一句话来说，&lt;br /&gt;看着比论文还难懂。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-7579960846531257462?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/7579960846531257462/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/09/dropbox-and-mu.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/7579960846531257462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/7579960846531257462'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/09/dropbox-and-mu.html' title='Dropbox and MU'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-7822677506143872003</id><published>2011-07-19T16:10:00.025+08:00</published><updated>2011-07-19T17:36:53.026+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 grams'/><title type='text'>The Matrix</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Gmail&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(153, 153, 153);"&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 153, 153); font-weight: bold;"&gt;with&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(192, 192, 192);"&gt;Call phone&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt; &lt;span style="font-weight: bold;"&gt;Mr &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Twitter&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;is a legendary geek jerk and psycho, he&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;doesn't&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;exist at all&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-obqGOekOzFk/TiVDldHKKbI/AAAAAAAAAGU/wo0Yq4mCsPQ/s1600/Blogger.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://3.bp.blogspot.com/-obqGOekOzFk/TiVDldHKKbI/AAAAAAAAAGU/wo0Yq4mCsPQ/s400/Blogger.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981219845548466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-jz-Z3eipZnU/TiVD2HE0vWI/AAAAAAAAAGk/GB7XkksuH9w/s1600/Dropbox.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://4.bp.blogspot.com/-jz-Z3eipZnU/TiVD2HE0vWI/AAAAAAAAAGk/GB7XkksuH9w/s400/Dropbox.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981505987951970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-0FarzoKskpo/TiVD9tJY-YI/AAAAAAAAAGs/huLu-d5udD4/s1600/Facebook.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://2.bp.blogspot.com/-0FarzoKskpo/TiVD9tJY-YI/AAAAAAAAAGs/huLu-d5udD4/s400/Facebook.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981636466735490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-rSKyqkKDr-M/TiVEFIl0fFI/AAAAAAAAAG0/hV4g-3ZVmJw/s1600/Gmail.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://4.bp.blogspot.com/-rSKyqkKDr-M/TiVEFIl0fFI/AAAAAAAAAG0/hV4g-3ZVmJw/s400/Gmail.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981764092820562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-yP7E6NTrtW0/TiVELJU-ehI/AAAAAAAAAG8/LyWqZLJRCio/s1600/Google%2Bdocs.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://2.bp.blogspot.com/-yP7E6NTrtW0/TiVELJU-ehI/AAAAAAAAAG8/LyWqZLJRCio/s400/Google%2Bdocs.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981867369822738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-8AI298KLzM8/TiVERE3tdWI/AAAAAAAAAHE/6mwW5ml9d0U/s1600/Google%2Bgroups.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://1.bp.blogspot.com/-8AI298KLzM8/TiVERE3tdWI/AAAAAAAAAHE/6mwW5ml9d0U/s400/Google%2Bgroups.jpg" alt="" id="BLOGGER_PHOTO_ID_5630981969252545890" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-vIT_YZzIz8k/TiVEaKu9KtI/AAAAAAAAAHM/hoYn6JCm-34/s1600/Skype.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://1.bp.blogspot.com/-vIT_YZzIz8k/TiVEaKu9KtI/AAAAAAAAAHM/hoYn6JCm-34/s400/Skype.jpg" alt="" id="BLOGGER_PHOTO_ID_5630982125445262034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-b3bHYG-1qM8/TiVEhO_78jI/AAAAAAAAAHU/jNb91T_u-uM/s1600/Youtube.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://3.bp.blogspot.com/-b3bHYG-1qM8/TiVEhO_78jI/AAAAAAAAAHU/jNb91T_u-uM/s400/Youtube.jpg" alt="" id="BLOGGER_PHOTO_ID_5630982246849311282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/Q4bao.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/RpCJE.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/QNwhI.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/gCPP4.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/XBpbQ.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/LdcWf.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/4sh71.jpg" title="Hosted by imgur.com" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i.imgur.com/sguS5.jpg" title="Hosted by imgur.com" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-7822677506143872003?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/7822677506143872003/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/07/matrix.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/7822677506143872003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/7822677506143872003'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/07/matrix.html' title='The Matrix'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-obqGOekOzFk/TiVDldHKKbI/AAAAAAAAAGU/wo0Yq4mCsPQ/s72-c/Blogger.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-6158315385987650504</id><published>2011-07-09T19:28:00.002+08:00</published><updated>2011-07-19T17:19:44.763+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>去医院挂专家号</title><content type='html'>&lt;pre&gt;   北京的三甲医院。都是老中医专家，最小的70多岁，最老的90多岁了。由于老中医属于稀缺资源，挂号&lt;br /&gt;就完全被票贩子控制了。其组织中最底层的专门负责占座排号，都是18，9岁的男孩女孩，见到的就有10多个，&lt;br /&gt;每人每个通宵给100元；有黑社会的负责安全，看到的就有4、5个；上面的是管理者，看到的也有4、5个。票&lt;br /&gt;贩子就在医院门口及走廊活动，显然医院的相关管理人员都是收他们的钱的。一个挂号医院要500元，结果票&lt;br /&gt;贩子卖5000，热门的专家号要7000，翻了10多倍! 你不买就得自己熬夜排号，第二天还不一定有号。&lt;br /&gt;&lt;br /&gt;   其中排号的那些小孩是东北、河北的。流动性很大，啥事都干，包括遣送上访人员、打人，也用他们，&lt;br /&gt;每次给200元，他们就是负责做最dirty的工作，一旦出大事了找替罪羊肯定也是找他们；黑社会的几个人都&lt;br /&gt;是东北的；30以上的管理者中有东北的，男的女的都有，其它人口音也是北方一带的。&lt;br /&gt;&lt;br /&gt;   正常情况下，老中医每次新老病人一共只接待10个人，每周只出一次诊。中医看病肯定都要多次，有的&lt;br /&gt;病人是每周去一次，有的是每半月去一次，这样每周就可能有空缺1、2个人的情况。如果有空缺，就加一个&lt;br /&gt;号，排号的人里选这个专家的第一个人就能拿到号看病了。&lt;br /&gt;&lt;br /&gt;   我早上7点半到了就开始等，要等24小时，直到第二天早上8点多才有结果。其中最关键的有3条:&lt;br /&gt;&lt;br /&gt;1. 晚上9点多会有人让用个人身份证登记，所以9点左右千万不能离开座位，登记的人都是挂牌流氓，一旦错&lt;br /&gt;  过，就很难补了。票贩子在登记的时候就专门找这个空档，一旦有人出去，他们就去补。&lt;br /&gt;&lt;br /&gt;2. 在晚上登记之前，票贩子会千方百计打听你的消息，千万别告诉他们你挂的专家名字，就说替别人排的，&lt;br /&gt;  不知道是谁，就是跟周围的人也不能说。因为一旦让他们知道，你又排在最前面，那即使加了号，他们也&lt;br /&gt;  有办法把加的号变没。这样就只有9点多登记的时候票贩子才知道你排哪个专家。&lt;br /&gt;&lt;br /&gt;3. 第二天早上7点多进电梯上11楼看是否加了号，会有保安跟着，要查身份证，因此如果是替别人排的，那&lt;br /&gt;  登记的那个人一定不能提前走。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   这里面的问题是很明显的: 9点多在外面走廊登记，第2天早上5点多进里屋继续排队，再等到7点多才上&lt;br /&gt;11楼领号。既然登记用的是身份证，为什么还要在登记的时候让排号的人说出要挂的专家名字呢? 根本没必&lt;br /&gt;要，这就是给票贩子送信的，给他们时间去做手脚。&lt;br /&gt;&lt;br /&gt;   我是中午就说挂谁的号了，因此票贩子一个又一个的打听我的情况。本来上午有个票贩子说我要排的那&lt;br /&gt;个专家有个加号，结果到了第二天早上就没了。手里有号去看病的人里有第一次去的，证实了确实加号了，&lt;br /&gt;也证实了票贩子确实做手脚了。还有个第二次去的，说他第一次是花了7k从票贩子手里买的号。而且排号的&lt;br /&gt;人都说，其它医院也都这样。&lt;br /&gt;&lt;br /&gt;   回来跟屋里的弟弟说，那弟弟是典型的工科男，而且是特别听上面话的那种。我说票贩子都是暴利，他&lt;br /&gt;说怎么会呢? 需要那么多人分配，那点钱也没多少啊，要是暴利那码农还写代码干啥还不如去干票贩子呢?&lt;br /&gt;我说底层排队的每个通宵才100元，而这一张票就能卖5k，他们每次都占7、8个座位，你算算就这一天得赚多&lt;br /&gt;少钱，全让上面分了，自然比码农赚的多多了。&lt;br /&gt;&lt;br /&gt;   深刻感受就是: 人治就是黑社会治。如果哪天我在北京没饭吃了，就去医院给黑社会排号去。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-6158315385987650504?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/6158315385987650504/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/07/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/6158315385987650504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/6158315385987650504'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/07/blog-post.html' title='去医院挂专家号'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-1783698542954756911</id><published>2011-06-29T18:46:00.005+08:00</published><updated>2011-07-05T10:17:29.152+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 grams'/><title type='text'>中日近代化学习能力比较</title><content type='html'>中日近代化学习能力比较&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    同样是1860年代开始学习西方，比较一下中日学习的结果。&lt;br /&gt;&lt;br /&gt;    日本在1868年明治天皇登基后，即派出使节团学习西方的先进治国经验。2年后归国，在这批平均年龄仅&lt;br /&gt;34岁的治国精英带领下，日本逐步走向了富强之路。&lt;br /&gt;&lt;br /&gt;    先学习最基础的四样: Freedom、Democracy、Law、Education。&lt;br /&gt;&lt;br /&gt;    大久保利通致力于经济、伊藤博文领导制定了庄严的宪法、木户孝允致力于教育......&lt;br /&gt;&lt;br /&gt;    1889年颁布宪法，1890年设立议会，1895年实行义务教育。&lt;br /&gt;&lt;br /&gt;    仅仅20年，治国的基本框架就搭建好了，让人不禁感叹日本人的快速学习和实践能力。&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;1.  1894年日清战争。&lt;br /&gt;&lt;br /&gt;    日本占领台湾。日本除了陆军获胜之外，海战中大清北洋水师全军覆没，日舰无一沉没。战舰的质量相&lt;br /&gt;当、数目相当，产生了如此悬殊的战果。日本人买战舰学会了精确的炮术；大清买战舰，水兵只学会了喝酒&lt;br /&gt;之后打架。20多年过去后，中日之间的学习能力已经分出高下了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2.  1904 ~ 1905 年日俄战争。&lt;br /&gt;&lt;br /&gt;    日俄两国在大清领土上开战。日本除了陆军获胜之外，还通过两次海战，歼灭了俄罗斯旅顺舰队和波罗&lt;br /&gt;的海舰队。巩固了日本在朝鲜和大连旅顺的殖民地，开创了东亚国家战胜欧美列强的先例，确立了日本强国&lt;br /&gt;的地位，此时距离明治天皇继位30多年。而此时的大清，只剩下宣布中立的胆子了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3.  大量日本汉语成为中国日常用语。&lt;br /&gt;&lt;br /&gt;    进入20世纪后，中国人经过了近40年的学习，发现连最基本的四样都弄不明白，别说更高级的技术了，&lt;br /&gt;只好向日本学习。&lt;br /&gt;&lt;br /&gt;    日本人将大量的西方词汇翻译成了日本汉语，那四样叫自由、民主、法律、教育。Republic 叫做"共和"，&lt;br /&gt;People 叫做"人民"......到今天，常用汉语中有 1/3 的词汇都是日本人翻译西方的；人文学科中则有 2/3&lt;br /&gt;的词汇是日本人翻译西方的；就连 PRC 这3个词汇的国名里也有2个是日本汉语。&lt;br /&gt;&lt;br /&gt;    这个时期，即使有些翻译并不符合中国习惯也开始囫囵吞枣了。将 Republic 翻译成"共和"，按照中国&lt;br /&gt;传统习惯根本看不出一丝"人民"的意思。虽然不懂日语，但可以猜测大和民族中的 "和" 应该有人民的意思。&lt;br /&gt;不过这种翻译方式为大量中国人喜欢，因为可以利用其模糊性骗人。&lt;br /&gt;&lt;br /&gt;    到了1930年代，日本人能独自生产世界一流的铁轨、建造自己的航母、建造世界上最大的战列舰、建造&lt;br /&gt;世界一流的零式战机......&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;4.  1928.6.4  关东军河本大作和东宫铁男策划炸死了张作霖，温柔乡将军上台，易帜，归顺国民政府。&lt;br /&gt;    1931.9.18 关东军板垣征四郎、石原莞尔策划了满洲事变，日军迅速占领中国东北。&lt;br /&gt;    1932.3.1  东北满洲国建立。&lt;br /&gt;    1937.7.7  中日战争爆发。&lt;br /&gt;    1941.12.8 日本偷袭美国珍珠港，太平洋战争爆发。&lt;br /&gt;    1945.8.15 日本宣布无条件投降，台湾、东北回归。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    关于中日战争、南京大屠杀和战后赔款，奸佞之徒造了很多谣，需要说明一下: &lt;br /&gt;&lt;br /&gt;1.  中日战争爆发是偶然的，互相不宣战是各有各的考虑。&lt;br /&gt;&lt;br /&gt;    日军在中国大门口演习，演习结束后日军回去做些收尾工作，中国的29军无法容忍，和日军发生了冲突。&lt;br /&gt;战争爆发后，双方都不肯让步，却又都不肯宣战，一边打一边谈，直到太平洋战争爆发后，双方才互相宣战。&lt;br /&gt;日方的战争资源主要靠进口，如果对中国宣战，很多国家根据中立法就不能向日本出口资源了，比如美国就&lt;br /&gt;不能向日本出口废铁，有的国家就不能向日本出口石油，因此日本决定不宣战；中国是弱国，即使有了资源&lt;br /&gt;也造不出来先进武器，靠英美外援，自然是更不能宣战了。后来双方打了4年多，由于法国投降，日本开始&lt;br /&gt;占领法国殖民地印度支那半岛，就是现在的越南半岛，这直接威胁美国在南亚的利益，因此对日本的石油贸&lt;br /&gt;易禁运，日本人不肯让步，轰炸珍珠港把美国拉下了水，有了这么强大的同盟还不对日宣战更待何时。&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;2.  东京审判和南京大屠杀。&lt;br /&gt;&lt;br /&gt;    战争审判和改朝换代一样，历来都是暴力的继续，没有道理可讲。对日本和德国战犯的审判都是战争结&lt;br /&gt;束后制定新规定，然后根据新规定审判旧犯人。 &lt;br /&gt;    &lt;br /&gt;    美国主导了对日本战犯的东京审判，最后有7名A级战犯被处死。由于太平洋战场是主导因素，发动太平&lt;br /&gt;洋战争的 东条英机 成了头号战犯，国民政府提交的若干战犯也被送上了绞刑架:&lt;br /&gt;&lt;br /&gt;    满洲事变的主谋 板垣征四郎 被定为A级战犯并处死；&lt;br /&gt;    将溥仪从天津秘密接往东北建立满洲国的 土肥原贤二，被国民政府列为头号战犯；&lt;br /&gt;    中日战争，当时的日本政府外相 广田弘毅，演讲向中国派兵，扩大事态，被列为A级战犯；&lt;br /&gt;    南京大屠杀时，广田弘毅作为外相，并未制止军部的行为，纵容军部，被判绞刑；&lt;br /&gt;    攻占南京城的将领 松井石根 也被送上了绞刑架；&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    南京大屠杀的责任当年已经由 松井石根、广田弘毅 承担了，这个事情至今还会被很多无知者翻出来转&lt;br /&gt;移矛盾。&lt;br /&gt;&lt;br /&gt;    整个审判过程也对比出了日本人和中国人的品格。&lt;br /&gt;&lt;br /&gt;    日本军部的高级将领除了自杀的，接受审判的将领都在极力为天皇辩护，而且不互相推诿责任，甚至满&lt;br /&gt;洲事变的第二主谋 石原莞尔 主动要求承担责任，经过调查发现他当年只赞成占领满洲，却反对发动太平洋&lt;br /&gt;战争，因而被日本军部降级，调离回国，盟国因此没有给他加罪；而满洲国皇帝溥仪就不同了，把责任都推&lt;br /&gt;到日本军人身上了，说他啥都是被迫的。实际情况是他和日本军方互相利用，各有各的好处可得，他想重建&lt;br /&gt;大清帝国，日本人想利用他控制中国东北。土肥原贤二 去天津的日租借找他谈，他说要是以大清的国号做&lt;br /&gt;皇帝他就去，日本人承诺可以做到并负责满洲国的安全，他这才去的，而且在位13年间几次访问日本。这本&lt;br /&gt;来就是你情我愿的事，最后失败了，那就各自承担责任就是了，毕竟大家在一起玩过。根据中国人的品性，&lt;br /&gt;溥仪这种做法一点都不奇怪。天天都是这种人在一起共事，要能有成果那才是稀奇呢。也暴露出中国帝王最&lt;br /&gt;高统治者们的真实面目，都是靠血腥上台的俗人。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3.  关于战争赔款。&lt;br /&gt;&lt;br /&gt;    日本人是被美国人征服的，因此战争结束后美国人不提赔款，谁也就不提了。美国人有了一战德国赔款&lt;br /&gt;的教训，知道赶尽杀绝将来只会造成更大的反弹。&lt;br /&gt;&lt;br /&gt;    到了1960年代，日本经济高速发展，韩国军政府开始和日本谈判，认为日方应该给予赔偿。但是赔偿数&lt;br /&gt;额很难确定，因为如果较真，日本人留在韩国的建筑都应该拆掉运回日本。日本人提出直接给受害人赔款，&lt;br /&gt;韩国军政府说直接给韩国政府就行了，政府负责处理细节。既然是谈判，必然双方都要让步。日本人让步了，&lt;br /&gt;最后给了5亿美元，其中3亿无偿、2亿有偿贷款，那时候美元比现在值钱，国库的储备基本都拿出来了；韩&lt;br /&gt;国人也让步了，这笔钱的名义不叫战争赔款，叫经济援助，这样既能保证韩国人有钱拿，又能让日本人避免&lt;br /&gt;说投降，双方在1965年签订了协议，终结此事。&lt;br /&gt;&lt;br /&gt;    问题是韩国政府之后没把这笔钱给受害人，而是用在了公共建设上，修路、建设钢铁厂.......有了神&lt;br /&gt;话般的汉江奇迹，到了1975年，人均收入是1965年的10倍。而韩国大量受害人根本不知道日本人给钱这件事，&lt;br /&gt;自然是向日本政府要了，让日本政府很是为难。直到大约2005年，韩国政府才把钱给到位，受害人终于得到&lt;br /&gt;了赔偿，日韩赔款适宜终于彻底了解了。&lt;br /&gt;&lt;br /&gt;    1972年，中美开始接触，共同对抗苏联，受美国控制的日本也和大陆建交。建交时自然涉及战争赔款，&lt;br /&gt;日方坚持不肯说投降，大陆鉴于苏联的威胁巨大，也就不再深究这个事，老周不敢做主，让老毛亲自拍板的。&lt;br /&gt;后来新人上台，和美国日本打的火热，美国日本对华的军事、经济援助保证了改革的启动和发展，属于盟国&lt;br /&gt;关系了，连钓鱼岛都不提了。30多年来，日本对华经济援助2000多亿美元，中国农村在80年代初中期的很多&lt;br /&gt;工程都是日本人拿的钱。这里面有没有什么协议就不知道了，自有后人评说。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    如今，在大连旅顺的龙王塘，每年的4月份都是看樱花的好季节，日俄战争日本获胜，日本人于1905年开&lt;br /&gt;始占领这里。去旅顺的路上就能发现一些日本当年的工程遗迹，包括山洞隧道。2005年去过一次，樱花是非&lt;br /&gt;常漂亮，其中有一座水坝很是引人注目，我先上去转了一圈，下来后若有所失，又回去爬上去重新转了一圈，&lt;br /&gt;回味了很久。大坝上有刻录的碑文，大概是: 着手于大正九年八月十九日，竣工于大正十三年三月三十一日。&lt;br /&gt;大正天皇1912年登基，因此可以知道大坝用时3年多，竣工于1924年。回来又查了资料，水坝高40米，占地面&lt;br /&gt;积254万平方米，蓄水面积3478万平方米。这座大坝快90年了，如今还在正常使用。&lt;br /&gt;&lt;br /&gt;    长春也是类似，有很多日本人70年前的建筑，现在都用的好好的。曾经好不容易听说个中国人建造的60&lt;br /&gt;多年的老建筑，一细打听知道是当年日本人打的地基！&lt;br /&gt;&lt;br /&gt;    家是沈阳的朋友也是深有同感，80年前的日本建筑还有很多在使用。&lt;br /&gt;&lt;br /&gt;    哈尔滨没去过，不清楚。1940年大连到哈尔滨的当时世界最快的火车要走12.5小时，如今大连到哈尔滨&lt;br /&gt;T开头的特快列车需要 9.5 小时。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    对比中日学习过程，看得出来那四样是立国的根本，技术属于更高级的层次，一个国家没有那四样就没&lt;br /&gt;有技术，只有愚昧无知。&lt;br /&gt;&lt;br /&gt;    同样是皇帝，明治天皇为首的皇族就敢于真正放弃权力，以宪法、议会来管理国家。这样肯为国家前途&lt;br /&gt;着想的皇帝，别说推翻了，就是想退位人民也不能同意，人们愿意用钱养着你，因为你是一盏指明灯，是一&lt;br /&gt;国人民榜样。在看看大清的最高层，天天吃喝玩乐，贪污腐化，却喊着让别人去爱国，一点廉耻心都没有。&lt;br /&gt;&lt;br /&gt;    日本人用30年学会的四样，中国人150年了还没弄明白。而且150年前是想学学不会，现在是千方百计避&lt;br /&gt;免接触，重理轻文。因为学文的人凡有所成都有自己的思想，甚至会嵌入性格中，伴随自己走完一生，不那&lt;br /&gt;么听话；而理工科的人就听话的多，尤其是工科的，给个踏实、聪明、强、效率高的名号，就会高兴得玩命&lt;br /&gt;干活，问题在于国外人文都有很好的基础，因此工科男都作出了很多原创技术，对社会发展贡献巨大，而没&lt;br /&gt;有人文基础的中国，根本没有技术需求，工科男都做些体力活。律师是一个国家特别重要的职业，维护宪法&lt;br /&gt;尊严，是人们生活有尊严的保证。可现在好律师都是防范的对象，一大堆都是政府指定的5毛律师；新闻学没&lt;br /&gt;有监督的权力，学的是如何按照上面的命令传播，很joke；出国读哲学，回国之后除了做5毛想不出还有啥有&lt;br /&gt;薪水的工作；历史学和政治学的人也很惨，一批流亡海外的，留在国内的不做5毛很难有饭吃。目前的趋势是&lt;br /&gt;跟日本学也跟不上了，下一步可以考虑向韩国或者印度学习。&lt;br /&gt;&lt;br /&gt;    文科没有出路，技术也没有。如今支撑经济发展的是"世界工厂"。英国当年也号称"世界工厂": 从落后&lt;br /&gt;国家进口原料，生产出来巧克力，高价卖给别人；中国现在也叫世界工厂，发达国家把工厂放在中国，中国&lt;br /&gt;人廉价工作，生产出来的东西低价卖回发达国家。&lt;br /&gt;&lt;br /&gt;    日本70年前就能造出7万多吨的驰骋太平洋的大和号战列舰，近来听说中国人买了个5万多吨的二手货，&lt;br /&gt;准备改造成航母；把德国日本的高铁技术买来就叫自主创新。没接触工科之前不懂其中的奥妙，因为中国人&lt;br /&gt;能做到一大批人共同说一个谎言，入行了才能懂其中的真谛。大陆工科男说做技术混口饭吃可以理解，谁都&lt;br /&gt;要养家糊口。但别占领高地说你是做 research 的，你们连 search 都没做呢何来的 re 啊？跟在发达国家&lt;br /&gt;后面跑龙套的事就不用拿出来占领高地了，先去做 search 的工作吧，日本人70年前的东西，你现在能做出&lt;br /&gt;来同样质量的，就算你能耐了！&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-1783698542954756911?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/1783698542954756911/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/06/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1783698542954756911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1783698542954756911'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/06/blog-post.html' title='中日近代化学习能力比较'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-4141170900349093407</id><published>2011-04-25T17:14:00.003+08:00</published><updated>2011-05-06T16:59:45.516+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>电费</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    几天前，晚上回去，发现楼张在门上贴了个纸条，说我1-3月的电费扣款不成功，让我找楼长。&lt;br /&gt;&lt;br /&gt;    这张纸条让我想到了近10年的电费问题，只通过这么一件小事，就能看清楚很多人的品性。&lt;br /&gt;&lt;br /&gt;    2001年9月，大连入学，宿舍很大，5个人，每个研究生给6度电费，超了另外交钱，每个字5毛左右。如&lt;br /&gt;果只用热得快烧水洗头，就超不了。11月初宿舍一个哥们的导师给他配了台电脑，开始是5个人用，后来我们&lt;br /&gt;几个陆续都不用了，就他自己用。2002年的寒假我去了山东，2003年的寒假我没回家，寒假期间用了他的电&lt;br /&gt;脑，开学后楼长让交前几个月的电费，虽然我只用了一个月，但20元、30元的也差不了多少。当时3个人在宿&lt;br /&gt;舍，我说就咱们两个人拿吧。他听错了，以为我不想拿，就大声问谁拿啊？我说咱俩拿么，他俩也没有电脑，&lt;br /&gt;总不能也让他俩拿吧，他说也是。然后第三个哥们很仗义地拿了10元给他，说我也拿10块吧，他竟然要了！&lt;br /&gt;对他印象一下子就跌了一大截。2003年8月我退学，学校也没赶人，我仍旧在宿舍住。接下来的2004年寒假我&lt;br /&gt;也没回家，但是没用他的电脑，去旁边一个宿舍用了几次。开学后，和第三个哥们聊天，听说我没用电脑，&lt;br /&gt;他惊讶的说有电脑你咋不用呢？我没说话，出去洗手了。2004年6月快毕业了，楼长贴出来电费45元，几个月&lt;br /&gt;来宿舍就我们2个人住，他用电脑，我就每周洗两次头，没几块钱，但知道他在意这个，就说我拿15，剩下你&lt;br /&gt;拿怎么样？他说OK。最后毕业了他说要和我吃散伙饭，我就没打算和他吃的，但他这么说了我就去了，两人&lt;br /&gt;花了50左右。饭是吃了，但我知道那是最后一面，以后是不会和他相处的。&lt;br /&gt;&lt;br /&gt;    2004年的上半年里，我才知道隔壁在电费上问题更大。他们屋有两个人合买了一台电脑，两个人每人一&lt;br /&gt;天，从来不关机，晚上通宵开着，几个月下来电费自然就多。然后买电脑那两个人说他们出 2/3，另外3个人&lt;br /&gt;出 1/3。这个建议真的不好，因为那3个人没电脑，学校给的电都够用了，不应该让人家拿钱的。那3个人也&lt;br /&gt;是我想的那样，不拿，而且人家觉得晚上不关机严重影响了人家睡觉。结果他们屋的电费攒了好几百，那关&lt;br /&gt;系僵的，跟我本科宿舍几个人差不多，见面都不打招呼。&lt;br /&gt;&lt;br /&gt;    在2004年的上半年里，猴子住另外一个宿舍，猴子好说话，我总去他们屋说笑，上午他出去自习的时候，&lt;br /&gt;我用他的机器写了一些 C 和 汇编 的小程序，这个期间我感受到了自己有一台电脑的重要性。下午他用机器&lt;br /&gt;的时候，我就用他的图书证去图书馆看书。有一天早晨，我说你啥时候去自习啊我用你机器，他说我今天不&lt;br /&gt;想自习了，想调试程序，我说那好，图书证借我，我去看书。他说没准一会我还想用证呢，我说那好，我就&lt;br /&gt;用机器，你用证我用机器，你用机器我用证。他苦笑着说: 老大，你饶了我吧! 这事到现在想起来还是笑的&lt;br /&gt;不行：）他爱吃老奶奶牌子的花生，一次做家教回来，我直接买了50块钱的老奶奶花生，一大塑料袋给他扔&lt;br /&gt;床上了。他吃了老长时间了，快毕业了吃不了很多都送人了。不过他身体确实调理的很好，到最后也没见他&lt;br /&gt;上火嘴上长瘡：）临毕业要交电费了，我留了50元说电费，他说不要，我说不行。结果过几天还是给我送回&lt;br /&gt;来了。&lt;br /&gt;&lt;br /&gt;    2004年下半年开始，租一个男博士的宿舍。可以在宿舍煮挂面，这哥们恐怕我不交电费，没事就说煮挂&lt;br /&gt;面要很多电吧，我说没事到时候我去交。但这哥们和我说话总有一副奴隶主的派头，事儿多，人很计较。刚 &lt;br /&gt;搬进去住，他说他有事要离开大连几天，让我去接他一个新入学的老乡，后来那天我专门在宿舍等着，他老&lt;br /&gt;乡给我打电话说不用我去接了。有一次，他说他有个朋友考研几次没考上，数学不行，我说哦。2005年年初&lt;br /&gt;的一天，他说他那个朋友过来了，想请我吃饭，我说不愿意和陌生人吃饭，他说没关系，她想年底让你帮他&lt;br /&gt;讲讲数学，我硬着头皮说那好吧，其实我是很反感和陌生人通过吃饭交往的。那女的来了，3个人在宿舍聊&lt;br /&gt;了能有2个小时，然后那女的请吃了一顿饭。过后他跟我说上次是他请那女的吃了，这次该轮到她请了。我 &lt;br /&gt;听了很鄙视他，一个男人这么计较，是朋友就不在意这个，要么不是朋友就干脆别扯这个，就吃顿饭还谁请 &lt;br /&gt;谁的，也不怕我笑话他。10多年前听老人讲，满洲国时期有路过的人饿了没钱吃饭了，就近找一家就要一顿&lt;br /&gt;饭吃，谁都不计较这个，哪象现在。到了12月初我给那女的讲了一次，能有2、3个小时。到了年底我收到一&lt;br /&gt;个短信，说觉得你人不错，祝福如何如何，我没回。第二天她打电话说我给你发短信祝你圣诞快乐你咋不回&lt;br /&gt;呢？我说接到几个短信都没敢回，怕回了要订业务。她怀疑的说不......会吧，我说会，祝你圣诞快乐。这&lt;br /&gt;个女的也是吉林的，98级的，在开发区一个中学做班主任，挺能说的，但我觉得和那么小气的男人都能做朋&lt;br /&gt;友，这个人我也不会交往，因此手机里压根就没存她的号。2006年我考上了北京的学校，她和我考一个学校，&lt;br /&gt;是MBA，也考上了。期间复试等等费劲了周折。我在外面做家教，得早起，在楼长来之前出楼; 晚回，在楼&lt;br /&gt;长走之后回来，很规律，一整天在外面特别累，回来吃完饭就睡觉了。都是早晨 7:20 准时起床，那哥们还&lt;br /&gt;没起呢我就走了，那哥们还没回来呢我就睡了。有一天早晨我起床了，他问我，***给你打电话了吗？我说 &lt;br /&gt;没有啊。他说***说她给你打了几次电话，我说不知道没接到。实际确实有几次接到了电话，一看号码像她 &lt;br /&gt;的就没接。又过了几天，我刚起来去洗脸，他在床上喊我说有电话，我也没着急，洗完脸才进屋，这时电话&lt;br /&gt;已经不响了，他说有人给你打电话，我一看是她的号码，回了声哦就走了。&lt;br /&gt;&lt;br /&gt;    2006年9月在北京入学，一个宿舍两个人，每个人8个字。他老板给他配了个本，我没有电脑，想用的时&lt;br /&gt;候只好去实验室。然后过了几个月，他就说他看一个美剧，里面一个宿舍的两个人平均交电费。我也没在意，&lt;br /&gt;以为他随便说说。后来他又说了一次电费，我才知道他是想我们两个人平均电费，也没在乎，才几个钱啊。&lt;br /&gt;有一天我回宿舍，他说停电了，他下去交电费，楼长不在，让我下去看看。我很不爽，去了隔壁，过一会儿&lt;br /&gt;我回宿舍，他又说你下去看看呢！我只好下去了，楼长不在。到了晚上，他跟我说电费交了2元，我没说话。&lt;br /&gt;计较电费的毕业后不交往。&lt;br /&gt;&lt;br /&gt;    2009年7月，两个弟弟搬了进来，都喜欢上网。其中一个弟弟很好，晚上我睡觉了他就小声；另外一个就&lt;br /&gt;不是了，过了12点才来劲，洗衣服、语音聊天，有时候大笑，有时候高兴了两脚来回跺脚......我也没说什&lt;br /&gt;么，毕竟年轻人，喜欢熬夜也正常。他东西多，我东西少，就把他一个大箱子放我床下了，跟那个懂事的弟&lt;br /&gt;弟说过几次话，但跟他从来没主动说过话。2010年12月的一天早晨，他突然从外面回来对另一个弟弟大声说：&lt;br /&gt;又交电费了，20多，以后就不用总下去交了，直接从卡里扣，3个人平分。那个弟弟听了犹豫的说：这...这&lt;br /&gt;....意思就是我就一周给刮胡刀充一次电，学校给我的电费我都用不了，手机为了方便都在实验室充，让我&lt;br /&gt;也平分电费是不是很过分啊。但这些话他没说出来，由于说话声音很大，我在床上也被吵醒了，我听了心理&lt;br /&gt;不舒服，但也没在乎，扣就扣吧，半年50块钱而已，为了点小事有摩擦犯不上。有趣的是接下来2011年1-3月&lt;br /&gt;的电费一直没扣，而由于这个学期老板不给我发钱，4月初我把学校的银行卡注销了，学校在4月份开始扣钱&lt;br /&gt;发现不成功，就找楼长给我门上贴纸条了，我还以为早就扣了呢。那个要求平分的弟弟今年3月份去香港了，&lt;br /&gt;宿舍就我和那个懂事的弟弟。但一是我兜里没钱了，再说即使有钱我也不会找楼长的，就算把电停了对我也&lt;br /&gt;没影响。想想这世界上啥人都有，用我的电量，把大箱子放我床下，背后却还要黑我，他不在晚上当着我的&lt;br /&gt;面说平分电费的事而在我睡觉的时候说，就是因为这话他说不出口。&lt;br /&gt;&lt;br /&gt;    要说这人大方和小气就体现在这里。中国人小气人占大多数，和欧美日本有着本质的差别。东北人挺大&lt;br /&gt;方的。一说东北人大方，就会有人用极端例子来反驳，说也没见东北人送我什么，那天给我买个吃的他还要&lt;br /&gt;拿几个。实际上，不是送人东西才叫大方，送人东西的那叫有目的，傻子才没事送别人东西呢。大方是说不&lt;br /&gt;计较小事。自己成大款了，去饭店吃饭，即使不给小费，那如果服务员不小心把汤撒裤子上了，不要试图让&lt;br /&gt;服务员赔，或者趁机减少点饭钱，不应该计较这个，这就叫大方; 如果能给底层人小费，多少不限，这就叫&lt;br /&gt;大方；在家里遇到要饭的饿极了，给几个包子吃，这就够了。东北人这些做的不错，因此我说东北人大方。&lt;br /&gt;1999年，初中同学白和徐来找我，聊了一阵一起去县城闫家玩。坐公汽，兜里揣着钱呢，快下车了徐走在前&lt;br /&gt;面给车票了，我也没说什么，相信她不会因为这个就觉得我小气的；2001年考研，我们四个人拼车，有次没&lt;br /&gt;找到车，就坐公汽回来，快到站了武要拿钱，我说钱在我手里呢，当然钱要不在我手里我也就不说什么了，&lt;br /&gt;谁有零钱谁拿就是了。&lt;br /&gt;&lt;br /&gt;    而为了一点电费斤斤计较，这就叫小气；自己不差钱，却剥削20出头的学生，别人每月给孩子发1200，&lt;br /&gt;他却非要发800。别人发800，他非要给孩子发400，这就不仅是小气，而且很缺德。别人发的就够少了，可 &lt;br /&gt;能不敢多发是怕得罪同僚，但本来就没几个钱却非要独树一帜继续少发几百，那就是缺德了，毕竟对方是弱&lt;br /&gt;势群体，不能赚钱。小气是教书匠的职业病，十个里面九个抠，因此得了个 "臭老九" 的名声。但过去的老&lt;br /&gt;师虽然小气却有学问人品也不差，现在的老师一大堆又小气人品又差学问更是一点没有，然后还在关键位置&lt;br /&gt;上; 小气也是绝大多数女人的专利，但女人小气不算毛病，跟小气的男人却不交往，因为交往起来太累，生&lt;br /&gt;怕不小心就欠了人家的人情，更怕有的占着便宜还会在背后黑我。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-4141170900349093407?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/4141170900349093407/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/04/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/4141170900349093407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/4141170900349093407'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/04/blog-post.html' title='电费'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-2546232411336896174</id><published>2011-03-02T13:16:00.016+08:00</published><updated>2011-07-01T17:21:46.790+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Understanding The Lion King</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    美国人1994年的动画片，就算和今天的动画片比较也毫不逊色，里面的音乐更是体现着非洲的狂野和对&lt;br /&gt;快乐的追求。即使是大人，要想完全看懂里面的很多细节也不容易，需要了解非洲大陆的生态。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1.  Lion VS Hyena&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-OztjeLYOvNo/Tg2LNqN8jEI/AAAAAAAAAC8/1HpP24aihpQ/s1600/king.JPG"&gt;&lt;img style="float:center; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://2.bp.blogspot.com/-OztjeLYOvNo/Tg2LNqN8jEI/AAAAAAAAAC8/1HpP24aihpQ/s400/king.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624304576442960962" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-ZWlqq-iI_DM/Tg2LVmZsA8I/AAAAAAAAADE/RFEFwgJgY98/s1600/hyena.JPG"&gt;&lt;img style="float:center; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://2.bp.blogspot.com/-ZWlqq-iI_DM/Tg2LVmZsA8I/AAAAAAAAADE/RFEFwgJgY98/s400/hyena.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624304712857420738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    首先要了解狮群的构成。在非洲大陆上，Lion是陆地上的顶级食肉动物，通常一个狮群有10多只，其中&lt;br /&gt;有一头或者两头雄狮子，它们是兄弟。雄狮子只负责守卫疆土，偶尔才参与猎食，比如母狮子正在抓捕强悍&lt;br /&gt;的Buffalo，很难搞定，如果King碰上了会帮忙。母狮子完全负责觅食，虽然食物是母狮子抓的，但如果让&lt;br /&gt;King见到了食物，那必须让King先吃，相当于收保护费。狮群内部矛盾重重，但捕食的时候都很合作，吃食&lt;br /&gt;的时候才互相撕咬。自然界的狮子极其残酷无情，可没有动画片里那么和睦温顺。比如有一个狮群发生过这&lt;br /&gt;样的事：有一只母狮子老了，其女儿也都生儿育女了，由于刚出生的小狮子喜欢打闹，这会让他们的祖母十&lt;br /&gt;分厌烦，而祖母一旦表现出来厌烦的态度，又会受到小狮子妈妈们的威胁，内部关系很不和谐。觅食的时候&lt;br /&gt;年轻的母狮子都出去了，留下祖母照看小狮子，结果当年轻的母狮子回来的时候，发现有的小狮子要么不见&lt;br /&gt;了，要么不知道被什么咬死了。直到1年多以后，才发现原来小狮子是被祖母咬死的！1年多来一共咬死了30&lt;br /&gt;多只小狮子！小狮子如果是公的，那长大后会威胁King的地位，比如吃食不让步，这时King就会赶他们出去，&lt;br /&gt;被赶出去的少年雄狮子会在各个狮群边界流浪，伺机夺权。一般King只能保持3~5年，新King会无情的咬死&lt;br /&gt;前King留下来的所有cub。&lt;br /&gt;&lt;br /&gt;    两只King虽然吃食的时候会撕咬，但不会象动画片里内讧的那么严重。&lt;br /&gt;&lt;br /&gt;    Lion并不是唯一的顶级食肉动物，最强劲的对手是 Hyena，就是欺负Simba的那三个家伙。Mufasa 告诉&lt;br /&gt;Simba不要去阳光照不到的地方，就是不让Simba闯入Hyena的领地。当然这是贬低Hyena，自然界中，Hyena的&lt;br /&gt;领地和Lion是挨着的，白天也是阳光普照。&lt;br /&gt;&lt;br /&gt;    Hyena 长的像狗，却属于猫科，因此中国人翻译成"髭狗"是不对的，还有的翻译成"土狼"就更瞎扯了。&lt;br /&gt;Hyena 形体比狮子小很多，但牙齿比狮子还厉害，能把骨头咬碎。一般30多只构成一群，有个Queen，matriarch，&lt;br /&gt;即使是最低阶的female也比任何一个male级别高。这和狮群不一样，狮群里除了King之外，其它Lion都平等，&lt;br /&gt;Hyena群体里则是每个个体都有严格的地位。动画片里的几只Hyena长相都比较萎琐，这并不是导演故意丑化&lt;br /&gt;它们，因为 Hyena 确实喜欢偷其它动物的猎物，比如 Leopard、Cheetah 的猎物被 Hyena 抢去那是家常便&lt;br /&gt;饭；甚至还常常趁乱跑到狮群里去偷小狮子吃；而且能消化腐肉，狮子只敢吃几口的腐肉，Hyena 吃得饱饱&lt;br /&gt;的也不会坏肚子：）&lt;br /&gt;&lt;br /&gt;    有时候7，8母狮子出去捕猎成功，正吃的时候，Hyena见到了就会来抢，刚开始母狮子占上风，不一会&lt;br /&gt;Hyena就会越来越多，30多只很平常，母狮子打不过就只好把扔下猎物跑了。但Lion King却是Hyena Killer，&lt;br /&gt;Hyena 只要见到King来了，不论身边多少只Hyena，掉头就跑。King体格健壮，脾气凶狠，上去直接就咬脖子，&lt;br /&gt;而且知道擒賊擒王，专门喜欢咬Queen。Hyena 生命力很强，有时候去别的Hyena的领地偷猎物，被人家发现&lt;br /&gt;咬掉了一只耳朵，没关系，过几天就好了；有的甚至嘴巴子被咬掉了一半，也没关系。当然由于形象有损，&lt;br /&gt;所以找对象的时候会失去优势，进而自己在族群中的身份会有所降低。&lt;br /&gt;   &lt;br /&gt;    Hyena 只要是肉就吃；Lion 也是几乎什么肉都吃，却不吃 Hyena，不知道为什么，也许是知道对方喜欢&lt;br /&gt;吃腐肉，觉得恶心吧：）&lt;br /&gt;&lt;br /&gt;    总之，Hyena凭借牙齿和数量的优势，地位比Lion低不了多少，经常为了地盘和食物争斗。后来Simba&lt;br /&gt;回去夺王位的时候，漫山遍野都是Hyena，就是强调它们的数量多。&lt;br /&gt;&lt;br /&gt;    而 Lion、Hyena 之间斗争最激烈的时候是晚上，十分血腥，好在人类看到的场面并不多。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    自然界中，不同动物对“群”的叫法不同:&lt;br /&gt;    Lion Pride； Hyena Clan； Wildebeest Herds； Wolf Pack； Fish Shoal ......&lt;br /&gt;    中国人不区分这些，狮群、牛群、狼群、羊群......都叫群，中国人区分的是舅叔、姑姨，美国人却不&lt;br /&gt;区分......一个关注封建等级辈份礼数，一个关注的是自然科学。对这些含义近似的词汇进行细腻的区别，&lt;br /&gt;可以看出西方人对科学的严谨态度。&lt;br /&gt;&lt;br /&gt;    西方人还区分 country 和 State。country 是强调风景物产风土人情时用的词汇，大指国家，小指小&lt;br /&gt;乡村；State 是和政治相关的词汇，小可以指地方州政府，大可以指国家政府。很多人的态度都是 &lt;br /&gt;Love Country Screw Government。&lt;br /&gt;&lt;br /&gt;    这里则体现出西方人所建立的现代政治架构。对绝大多数人来说，生在哪从哪里长大就会觉得哪里好，&lt;br /&gt;就是所谓的乡恋。正因为 country 是个绝大多数人都喜欢的词汇，所以就有人把自己和country绑定，然&lt;br /&gt;后作出声明: 你热爱country就是热爱他，你不热爱他就是不爱country，就是汉奸。&lt;br /&gt;&lt;br /&gt;看看 country 和 State 的解释:&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;country  noun (plural countries)&lt;br /&gt;  1  [C] an area of land that has or used to have its own government and laws:&lt;br /&gt;European countries * leading industrial countries * She didn't know what life in a foreign country would be like. * It's good to meet people from different parts of the country.&lt;br /&gt;  2  [U] (often following an adjective) an area of land, especially with particular physical features, suitable for a particular purpose or connected with a particular person or people:&lt;br /&gt;open / wooded country * superb walking country * Explore Thomas Hardy country.&lt;br /&gt;  3  (the country) [sing.] the people of a country; the nation as a whole:&lt;br /&gt;They have the support of most of the country. * The rich benefited from the reforms, not the country as a whole.&lt;br /&gt;see also MOTHER COUNTRY, THE OLD COUNTRY, UP-COUNTRY&lt;br /&gt;  4  (the country) [sing.] any area outside towns and cities, with fields, woods, farms, etc:&lt;br /&gt;to live in the country * We spent a pleasant day in the country. * a country lane -&gt; LANDSCAPE&lt;br /&gt; 5  [U] = COUNTRY-AND-WESTERN:&lt;br /&gt;pop, folk and country&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;......&lt;br /&gt;  2  (also State) [C] a country considered as an organized political community controlled by one government:&lt;br /&gt;the Baltic States * the State of Israel * European Union member states&lt;br /&gt;see also CITY STATE, NATION STATE, POLICE STATE, WELFARE STATE -&gt; COUNTRY&lt;br /&gt;  part of country&lt;br /&gt;  3  (also State) [C] (abbreviation St.) an organized political community forming part of a country:&lt;br /&gt;the states of Victoria and Western Australia * the southern States of the US&lt;br /&gt;  government&lt;br /&gt;  4  (also the State) [U, sing.] the government of a country:&lt;br /&gt;matters / affairs of state * people who are financially dependent on the state * a state-owned company * They wish to limit the power of the State.&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Wildebeest&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-wRqV43-R9lc/Tg2RY9AIynI/AAAAAAAAAEU/zzC1pxDEUwY/s1600/Wildebeest.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://3.bp.blogspot.com/-wRqV43-R9lc/Tg2RY9AIynI/AAAAAAAAAEU/zzC1pxDEUwY/s400/Wildebeest.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624311367533644402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    Hyena 惊动了 Wildebeest，Mufasa为了救Simba被踩死。&lt;br /&gt;&lt;br /&gt;    Wildebeest 哪里有青草就去哪里，是肉食动物的主食，往往和Zebra一起。太阳的移动导致了降雨的不&lt;br /&gt;断南北移动，青草也就跟着移动，Wildebeest 跟着青草走，去的路和回来的路不同，形成了一个环行路线。&lt;br /&gt;路途艰险，陆地上有 Lion、Hyena、Leopard，水里有croc，会被吃掉很多，但由于数量庞大，因此能使生&lt;br /&gt;态得以平衡。刚出生的 Wildebeest 在几分钟之内必须站起来，因为周围有很多猎物，生命在这里就是争分&lt;br /&gt;夺秒。牛群一旦被惊吓到是很可怕的，一跑起来就来不及躲避，因此见什么撞什么。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-gdgf1k76ipA/Tg2Od1OdB4I/AAAAAAAAAD0/VmJGaKkgR3k/s1600/buffalo.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://4.bp.blogspot.com/-gdgf1k76ipA/Tg2Od1OdB4I/AAAAAAAAAD0/VmJGaKkgR3k/s400/buffalo.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624308152810669954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    和 Wildebeest 长相类似的就是 Buffalo，电影里没有出现。Buffalo 更加强壮，牛角十分厉害，因此 &lt;br /&gt;Hyena 抓不了，Lion 也只有没食物了才抓 Buffalo，而且都从后面下手，以免被牛角伤到。有个别狮群比较&lt;br /&gt;勇猛，不介意在前面攻击，结果一只一只的都死于牛角之下。在非洲大陆的草食动物中，Buffalo 是反抗 &lt;br /&gt;Lion 最有杀伤力的。&lt;br /&gt;&lt;br /&gt;    北美还有一种牛和它们很像，也是群居，叫 Bison，《Dances With Wolves》里面的就是，影片里的&lt;br /&gt;Indian主角称它们为 Buffalo，也许是受非洲黑人英语叫法的影响。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. Warthog and Meercat&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-VS2rxoEPayM/Tg2RkSSOLRI/AAAAAAAAAEc/N_0YAO54bcw/s1600/warthog.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://3.bp.blogspot.com/-VS2rxoEPayM/Tg2RkSSOLRI/AAAAAAAAAEc/N_0YAO54bcw/s400/warthog.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624311562225200402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    Simba 被两个可爱的小动物救了，而且改变了人生哲学，学会寻找快乐。大的那个就是Warthog，属猪科。&lt;br /&gt;Warthog 住在地下的洞里，有的偷懒洞穴太浅，那赶上点背碰上饥饿的狮群，被从地下挖出来吃掉很常见。&lt;br /&gt;嘴边那两只牙很有用，当躲在洞里，有肉食动物试图从洞口伸进去脑袋攻击的时候，那两只牙可以轻易弄瞎&lt;br /&gt;对方的眼睛。Hyena 和 Leopard Cheetah 也吃它，因此它胆子很小，平时会有好几个洞，遇到危险就近避难。&lt;br /&gt;顺便提一句Cheetah，是短跑速度最快的动物，但是体型太苗条，跟别人抢食抢不过人家。Leopard 也属豹科，&lt;br /&gt;但比 Cheetah 强壮一些。有的电视广告是 Cheetah 追美女，以前觉得很无厘头，仔细观看 Cheetah 的体型，&lt;br /&gt;和女人一样苗条漂亮，尤其是双肩部位，简直就是女人的肩膀。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-ZLpUtay5-uY/Tg2PEFkziUI/AAAAAAAAAD8/gAK9ielocEY/s1600/leopard.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://3.bp.blogspot.com/-ZLpUtay5-uY/Tg2PEFkziUI/AAAAAAAAAD8/gAK9ielocEY/s400/leopard.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624308810034415938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-bYhkXves2Zs/Tg2POBy39LI/AAAAAAAAAEE/19_4CCArmxE/s1600/cheetah.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://3.bp.blogspot.com/-bYhkXves2Zs/Tg2POBy39LI/AAAAAAAAAEE/19_4CCArmxE/s400/cheetah.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624308980818375858" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    小的那个是 Meercat，电视里常见，荒原地带用尾巴支住身体，脑袋四处警戒，一有危险撒腿就跑。平&lt;br /&gt;时吃些植物和小虫子，也吃蝎子。不能怪它胆子小，因为几乎所有食肉动物都能吃它们，包括天上的 eagle。&lt;br /&gt;见到蛇它们就排成一列把蛇赶走，除非搬家，否则一辈子都不出远门，就在家门跟前转悠。虽然自然界里&lt;br /&gt;Meercat 和 Warthog 不会在一起生活，但是动画片里把它们两个胆小鬼放在一起，就有了娱乐效果。&lt;br /&gt;&lt;br /&gt;    有个长相和 Meercat 相似的，电影里没有出现，叫 Mongoose，这家伙可比 Meercat 凶猛多了，&lt;br /&gt;喜欢吃老鼠、蛇，很多连 Lion 都要躲着的 King Cobra 都丧命在它的嘴下。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-DN1vgGlvM9I/Tg2OF37wLLI/AAAAAAAAADs/tpsYkmVMrdY/s1600/mongoose.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://3.bp.blogspot.com/-DN1vgGlvM9I/Tg2OF37wLLI/AAAAAAAAADs/tpsYkmVMrdY/s400/mongoose.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624307741220678834" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. Baboon&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-0Ebwq3o0zws/Tg2NBXRGNqI/AAAAAAAAADc/HViF776dYv8/s1600/baboon.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://3.bp.blogspot.com/-0Ebwq3o0zws/Tg2NBXRGNqI/AAAAAAAAADc/HViF776dYv8/s400/baboon.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624306564220728994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    电影开头一个Baboon给Simba做诞生的祝福仪式。Baboon群居在树上，有时候到陆地上玩耍觅食，同时要&lt;br /&gt;防备Lion、Hyena、Eagle，所以大草原上不会有Baboon加入狮群的时候。对Leopard则不那么怕，单打独斗不&lt;br /&gt;行，但Leopard是独居，Baboon是一群，所以多数情况都是Baboon欺负Leopard，Leopard 尽量躲着Baboon。&lt;br /&gt;Baboon平时喜欢和antelope在一起，它们负责从空中警戒，antelope则擅长从地面上警戒，这样双方都更加&lt;br /&gt;安全。&lt;br /&gt;&lt;br /&gt;    antelope 有很多种，形体不大，长两只角。最常见的就是 Springbok，遇到危险一跳一跳的。还有&lt;br /&gt;Impala，Gazelle，它们都是肉食动物最喜欢吃的，因此时刻处于警戒状态，短跑能力强。&lt;br /&gt;&lt;br /&gt;    Baboon 还有两个primate亲戚 Gorila、Chimpazee，它们都没在电影里出现。其中 Chimpazee 皮肤黝黑，&lt;br /&gt;是除去人类之外最聪明的动物。对比一下，Gorila 只会用石头砸栗子，Chimpazee 不但会砸栗子，还会掌握&lt;br /&gt;用力的程度，能做到刚好把栗子壳打碎，又不砸碎里面好吃的果肉。&lt;br /&gt;&lt;br /&gt;    电影里还有很多动物只是露面，不是主角，但认识认识有好处，说不定下一个动画片它们就成主角了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5.  Croc and Hippo&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-Q2ENaJcc8KI/Tg2NkLl1GCI/AAAAAAAAADk/phj5zaM2uZ0/s1600/croc.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://1.bp.blogspot.com/-Q2ENaJcc8KI/Tg2NkLl1GCI/AAAAAAAAADk/phj5zaM2uZ0/s400/croc.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624307162381883426" /&gt;&lt;/a&gt;&lt;br /&gt;    &lt;br /&gt;    Croc 是肉食动物，Hippo是草食动物，它们经常泡在一个水坑里生活，有点不可思议。更不可思议的是&lt;br /&gt;连陆地上的Lion、Buffalo都照吃不误的Croc，竟然不敢惹吃草的 Hippo，还尽量躲着。刚出生的小Hippo无&lt;br /&gt;论怎么在Croc身上打闹，Croc也不敢发脾气。后来了解了 Hippo 才知道这家伙虽然不吃肉，却能咬人。它有&lt;br /&gt;上下两对大门牙，内斗的时候咬得对方遍体鳞伤，Croc不傻，看到Hippo打架的场面，自然就知道它们的厉害&lt;br /&gt;了。Croc 是不怕Lion的，有时候Lion去它的领地喝水，它不高兴就爬上岸边往那一趴，谁要敢去它就咬谁。&lt;br /&gt;&lt;br /&gt;    Hippo 白天就在水坑里晒太阳，晚上才上岸吃草。晚上是 Lion、Hyena 的天下，陆地上十分危险。但就&lt;br /&gt;算 Lion 也很少攻击 Hippo，因为Hippo重3吨左右，皮糙肉厚，很难搞定，常常拖着3只Lion跑。有一次5，6&lt;br /&gt;只 Lion 费尽力气可算把一只 Hippo 撂倒了，一只Lion却被Hippo砸得不能动弹了，然后 Hippo 爬起来继续&lt;br /&gt;跑，另外的 Lion 也不敢再追了。被砸伤那只 Lion 躺了足足一个礼拜才能起来走路：）&lt;br /&gt;&lt;br /&gt;    非洲大陆气候炎热，缺水。有时一个不大的水坑里面挤满了Croc、Hippo，赶上特别的年份，坑里几十头&lt;br /&gt;大型动物全被渴死了。&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6.  Rhino  Elephant  Giraffe&lt;br /&gt;   &lt;br /&gt;    这几个都是大家伙，影片里都出现了。如今Rhino已经被偷猎的捕杀的没几只了；Elephant 群居，内部&lt;br /&gt;之间交流的时候会叫，低频和高频部分人类听不到，但仪器能检测到。Lion 轻易不攻击 Elephant，但不绝&lt;br /&gt;对，如果Elephant受伤了或者到了晚上就会攻击了，Elephant夜间视力不好，Lion 却是夜眼。Lion 轻易也&lt;br /&gt;不攻击Giraffe，追不上，但饿极了也有攻击成功的时候。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;7.  Vulture  Ostrich&lt;br /&gt;   &lt;br /&gt;    这两个鸟类影片里出现了，Vulture 就是吃腐肉的，视力超群，哪里有动物死了，第一个发现往往是它。&lt;br /&gt;Simba 昏倒在陆地上的时候，就有好几只 Vulture 围着它转，等Simba断气了就吃掉Simba。Hyena 就利用这&lt;br /&gt;点，草木太繁盛了看不清周围的情况，就总往天上看，Vulture 飞到哪里它就往哪跑。Ostrich 体格较大，&lt;br /&gt;跑的快，两只爪子很厉害，踹正了直接能给对方开膛，所以肉食动物基本不抓它。只见到过3只Leopard抓到&lt;br /&gt;一只，很不容易。&lt;br /&gt;&lt;br /&gt;    非洲草原没有tiger、bear、wolf。因此无法比较一只Lion和一只tiger哪个更厉害。但其它大陆的野外&lt;br /&gt;bear 和 tiger 是能相遇的，tiger 都是从背后下手，而 bear 无论前后都敢攻击，确实是bear更厉害一些。&lt;br /&gt;非洲大陆有Jackal，独居，体型小，比wolf能力差多了。而被中国人称为"土狼"的是北美的Coyote，体型比&lt;br /&gt;Wolf 小，才40斤左右，比 Wolf 弱多了。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-IdVLX4dDFEI/Tg2QXCmWRrI/AAAAAAAAAEM/YB3e-Gn5plc/s1600/jackal.JPG"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://2.bp.blogspot.com/-IdVLX4dDFEI/Tg2QXCmWRrI/AAAAAAAAAEM/YB3e-Gn5plc/s400/jackal.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5624310235164722866" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;    群居动物有个共同的规则：群里面所有的female都归King所有，其它male都不许碰。因此King不是好当&lt;br /&gt;的，尤其是primate，一方面要抵御外敌和同类的竞争者，还要让female爽，你做不到她就给你戴帽子。即耗&lt;br /&gt;体力又耗神，所以3年左右就让位了。&lt;br /&gt;&lt;br /&gt;    1993年、1994年大姐家养了30多头羊，其中有一头公的种羊。羊得天天放，山羊是每天必须要走8里路，&lt;br /&gt;不然就掉膘，绵羊也差不多，放假了我就跟姐夫去放。平时用棍赶羊的时候没什么问题，到了母羊发情的时&lt;br /&gt;候就不一样了，有次一只母羊非要去路边别人家苞米地吃叶子，姐夫就用棍子多打了母羊几下，结果不大一&lt;br /&gt;会，那只大公羊用羊角对着姐夫的腿就是一下，腿疼了好几天：）接下来我就不敢拿棍子打母羊了，公羊却&lt;br /&gt;看着我也要来顶，而平时它趴下休息的时候我骑它身上它都不声不响的，很多兄弟为了女人掰了，从动物身&lt;br /&gt;上最能看的明白。而小羊羔生下来几天就很能跑，就是耐力不行。有一次母子两个掉对了，我回去找，它们&lt;br /&gt;两个见到我了就往家跑，我就在后面追，小羊羔才生下几天，大冬天的跑了有200米实在跑不动了，站那咩咩&lt;br /&gt;的叫。母羊就回来到它身边，我到跟前把小羊羔抱起来继续走，母羊就横在我腿上，不让我往前走，我绕过&lt;br /&gt;它就抱着小羊羔跑，母羊就在后面追，成了羊追我了，母羊一边追一边叫，怀里小羊羔也咩咩的叫，俨然我&lt;br /&gt;就是个偷小孩的人贩子。&lt;br /&gt;&lt;br /&gt;    了解了这些动物之间的关系，以后看动画片就会感觉更亲切了。&lt;br /&gt;&lt;br /&gt;    人类的很多性情都和上面的动物相似。现在很多非洲国家互相杀戮，残忍、野蛮、原始都表现在了现代&lt;br /&gt;的摄像机上，比如有的地方的人清理牛粪用手不用工具；有的地方的少年见到牛撒尿的时候，就跑过去用尿&lt;br /&gt;洗头：）&lt;br /&gt;&lt;br /&gt;    人类社会也有不如动物的方面。动物界有King，这个King在平时享受好处，有外敌时也会冲锋在第一线。&lt;br /&gt;而人类有King的体制却不是这样，平时享受好处，有外敌了却躲在后面让别人冲锋。因此人类学动物建立起&lt;br /&gt;有King的体制并非原本的King体制；人类也学过哲学家幻想过的体制，实践证明也是经过篡改的。好在西方&lt;br /&gt;有先贤建立了一套分权体制，no king no queen，对待有权力的人，就象对待野兽一样放笼子里。想拥有权&lt;br /&gt;力就进笼子里，不进笼子就没权力。强制让有权力的人意识到: 你们的权力是有限的，一分权力，一分责任。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The.Lion.King.1994.88min.mkv&lt;br /&gt;http://www.megaupload.com/?d=V97WXUNL&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-2546232411336896174?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/2546232411336896174/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/03/understanding-lion-king.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/2546232411336896174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/2546232411336896174'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/03/understanding-lion-king.html' title='Understanding The Lion King'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-OztjeLYOvNo/Tg2LNqN8jEI/AAAAAAAAAC8/1HpP24aihpQ/s72-c/king.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-5136226727027761045</id><published>2011-02-11T20:50:00.063+08:00</published><updated>2011-09-03T10:59:48.853+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux install'/><title type='text'>Audio/Video</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    处理视频，Windows 下有很多图形界面的工具，由于涉及到视频、音频、字幕...参数太多，图形界面太&lt;br /&gt;复杂，想告诉别人处理过程还得截图，此时 Linux commandline 的优势出来了，用起来比图形界面简单易懂。&lt;br /&gt;&lt;br /&gt;    区分 video format 和 codec。avi mkv mp4 都属于format，被称为container，里面包含video、audio、&lt;br /&gt;sub，对应有 vcodec、acodec、scodec。&lt;br /&gt;    &lt;br /&gt;    Windows 为了方便普通用户，把文件的扩展名用类似 format 的名字来表示，有的就是 format 名字本身。&lt;br /&gt;因此Windows下想知道视频的format就看扩展名:&lt;br /&gt;    .avi .mp4 .rm .vob 和其format名相同&lt;br /&gt;    .mpg format名是 mpeg&lt;br /&gt;    .mkv format名是 matroska&lt;br /&gt;&lt;br /&gt;    当然用扩展名也有坏处，比如一个a.rar可能无法解压，因为这个a.rar是由一个电脑新手把a.txt直接改&lt;br /&gt;名成a.rar的；或者下了一个.torrent无法下载，实际是制作人把.torrent压缩成了zip，然后又改名成.torrent。&lt;br /&gt;Linux 下就没这类问题，解压不了就用file命令看一下真正的format，然后用相应的工具处理。把foo.avi改名&lt;br /&gt;为foo，也照样能用 $ mplayer foo 播放。&lt;br /&gt;&lt;br /&gt;    通常文件扩展名就代表文件的format，但由于用户可以任意修改扩展名，所以拿来一个新文件，无法确&lt;br /&gt;定a.avi 就是 avi format，普通用户在这里会被误导。&lt;br /&gt;&lt;br /&gt;    这里也看出来 Windows 那一套机制都是给傻瓜用户用的，方便却糊里糊涂；Linux 是给大学生用的，不&lt;br /&gt;方便但是有利于培养思考能力。有些国家连计算机系的大学生都普及 Windows，就可以知道这个国家没有原&lt;br /&gt;创技术，也不崇尚创新，大学都是衙门，不是培养人才之地。&lt;br /&gt;&lt;br /&gt;    查看 format 和 codec:&lt;br /&gt;    $ ffmpeg -formats|less&lt;br /&gt;    $ ffmpeg -codecs|less&lt;br /&gt;&lt;br /&gt;file 命令看 format 和 codec:&lt;br /&gt;$ file * &lt;br /&gt;foo.DAT:              RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;foo.mpg:              RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;foo.vob:              MPEG sequence, v2, program multiplex&lt;br /&gt;foo.wmv:              Microsoft ASF&lt;br /&gt;foo.asf:              Microsoft ASF&lt;br /&gt;foo.rm:               RealMedia file&lt;br /&gt;foo.mkv:              Matroska data&lt;br /&gt;foo.mp4:              ISO Media, MPEG v4 system, version 1&lt;br /&gt;foo.m4v:              ISO Media, MPEG v4 system, iTunes AVC-LC&lt;br /&gt;foo.mov:              ISO Media, Apple QuickTime movie&lt;br /&gt;foo.flv:              Macromedia Flash Video&lt;br /&gt;foo.ts:               MPEG transport stream data&lt;br /&gt;foo.avi:              RIFF (little-endian) data, AVI, 640 x 480, 25.00 fps, video: XviD, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)&lt;br /&gt;foo1.avi:             RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: H.264 X.264 or H.264, audio: MPEG-1 Layer 3 (stereo, 22050 Hz)&lt;br /&gt;foo2.avi:             RIFF (little-endian) data, AVI, 352 x 256, 30.00 fps, video: DivX 5, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)&lt;br /&gt;foo3.avi:             RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: Motion JPEG, audio: uLaw (mono, 8000 Hz)&lt;br /&gt;&lt;br /&gt;    常见 format: avi mkv mp4 vob mpg mov wmv rm ...&lt;br /&gt;    常见 vcodec: MPEG-1 MPEG-2 MPEG-4 H.264 wmv3 RV40...&lt;br /&gt;    常见 acodec: AAC ac3 libmp3lame wmav2 cook ...&lt;br /&gt;&lt;br /&gt;    其中 H.264 是最流行的 vcodec，也叫 MPEG-4 AVC、MPEG-4 part 10，对cpu等硬件要求较高，目前高&lt;br /&gt;清用 H.264、MPEG-2 的最多。&lt;br /&gt;    &lt;br /&gt;    DVD 电影扩展名为 .vob，MPEG-2 + ac3、dts，vbitrate: 7Mbps&lt;br /&gt;    720P、1080P 高清电影扩展名多为 .mkv .mp4，H.264 + ac3、dts，vbitrate: 5Mbps、10Mbps&lt;br /&gt;    Blu-ray Disc 蓝光盘电影扩展名多为 .ts .m2ts   H.264、MPEG-2 + ac3、dts，vbitrate: 36Mbps&lt;br /&gt;    手机等掌上设备: mp4，MPEG-4&lt;br /&gt;    iphone 主要支持的format: mp4 mov m4v，优势是支持 H.264，也就是能看高清电影&lt;br /&gt;&lt;br /&gt;    .mov 多用来做高清1080P的电影预告片: True.Grit.2010.12.25.1080P.预告片.mov&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    想起了一个MM征友，说要找有品味的，比如平时谈论的是苹果五代，而不是五袋苹果的人。显然我是没&lt;br /&gt;品味的那种，因为我平时只喜欢谈论五袋苹果，不喜欢谈论苹果五代。&lt;br /&gt;&lt;br /&gt;    还有两个format平时压片尽量别用，因为它们商业味太浓，处理起来特别麻烦，尽量别用:&lt;br /&gt;    .rm           RV40 + cook&lt;br /&gt;    .wmv .asf     wmv3 + wmav2&lt;br /&gt;&lt;br /&gt;    视频操作先考虑专用工具，比如 mkvtollnix, mp4box，实在不行再用 ffmpeg，以前一直用 mencoder，&lt;br /&gt;后来发现ffmpeg问题少些，以后陆续转移到ffmpeg上来。虽然mencoder毛病很多，但由于ffmpeg无法合并视&lt;br /&gt;频，所以不能完全舍弃 mencoder。man mencoder 很有挑战性，和 mplayer 一起，参数多，跨度大，这个&lt;br /&gt;熟练后，在 man 什么都不怕了。&lt;br /&gt;&lt;br /&gt;    生成的视频 linux mplayer 总能很好的播放，所以一定要到Windows下去验证，最好直接mount一个NTFS，&lt;br /&gt;把生成的视频直接放上面。转换会有很多问题，比如转换后参数没有保持默认:bitrate被降低、视频的长宽&lt;br /&gt;比例DAR被改变、生成的视频信息封装不完整导致 file 无法识别...&lt;br /&gt;$ file out.mp4&lt;br /&gt;out.mp4: data&lt;br /&gt;&lt;br /&gt;    还有就是，无论什么方法，转换后的视频质量都会低于原质量，因此普通质量的视频无需转换，只转换&lt;br /&gt;蓝光、1080P、720P 的视频。&lt;br /&gt;&lt;br /&gt;1. 处理 mkv 用 mkvtoolnix&lt;br /&gt;$ sudo yum install mkvtoolnix&lt;br /&gt;&lt;br /&gt;生成一个mkv:&lt;br /&gt;$ mkvmerge foo.avi -o out.mkv&lt;br /&gt;$ file out.mkv&lt;br /&gt;out.mkv: Matroska data&lt;br /&gt;&lt;br /&gt;截取一段mkv。一个720P高清视频 Lin.mkv，H.264 vcodec:&lt;br /&gt;$ mkvmerge Lin.mkv --split timecodes:00:36:51,01:11:00 -o out.mkv&lt;br /&gt;生成3个mkv文件:&lt;br /&gt;out-001.mkv&lt;br /&gt;out-002.mkv&lt;br /&gt;out-003.mkv&lt;br /&gt;第二个就是想要的，码率会有很小的损失，Linux 下mplayer 或 Windows 下 Kmplayer 都能正常播放。&lt;br /&gt;目前无法直接截取第二段，可以在第二个文件split完成后手动中断mkvmerge进程。&lt;br /&gt;虽然 ffmpeg 能直接截取第二段，但操作H.264特别慢，而且不好控制，还不如直接来。&lt;br /&gt;&lt;br /&gt;合并mkv:&lt;br /&gt;$ mkvmerge 1.mkv + 2.mkv -o out.mkv&lt;br /&gt;&lt;br /&gt;港片国粤双语，只保留粤语:    ffmpeg -i 看视频参数&lt;br /&gt;$ ffmpeg -i 花样年华.2000.98min.mkv&lt;br /&gt;......&lt;br /&gt;  Duration: 01:38:51.47, start: 0.000000, bitrate: N/A&lt;br /&gt;    Stream #0.0: Video: h264, yuv420p, 668x480 [PAR 5760:4739 DAR 8016:4739], PAR 203:167 DAR 203:120, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Source:R1-US-DVD9 CRITERION COLLECTION&lt;br /&gt;    Stream #0.1: Audio: aac, 48000 Hz, stereo, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Cantonese&lt;br /&gt;    Stream #0.2: Audio: aac, 48000 Hz, stereo, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Mandarin&lt;br /&gt;    Stream #0.3(chi): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : chs&lt;br /&gt;    Stream #0.4(chi): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : cht&lt;br /&gt;    Stream #0.5(eng): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : eng&lt;br /&gt;&lt;br /&gt;可见，有2条音轨，3种字幕。要第1条audio Cantonese、前两个中文字幕chs cht。&lt;br /&gt;&lt;br /&gt;也可以用 $ mplayer -v 花样年华.2000.98min.mkv    找出 -aid 音轨号，听听验证一下:&lt;br /&gt;$ mplayer -aid 0 花样年华.2000.98min.mkv&lt;br /&gt;$ mplayer -aid 1 花样年华.2000.98min.mkv&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 花样年华.2000.98min.mkv&lt;br /&gt;File '花样年华.2000.98min.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_AAC)&lt;br /&gt;Track ID 3: audio (A_AAC)&lt;br /&gt;Track ID 4: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 5: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 6: subtitles (S_TEXT/UTF8)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 2 -s 4,5 花样年华.2000.98.min.mkv -o out.mkv &lt;br /&gt;out.mkv 确实就是粤语，码率损失很少，容量减少了约30MB。&lt;br /&gt;&lt;br /&gt;    一个视频一般只关心 Video、Audio、Subtitle 3个方面，mkvmerge -i 把这3类信息统一用一串&lt;br /&gt; Track ID 表示出来了，只要从这3个方面考虑，就很容易却别这些 TID 了。&lt;br /&gt;&lt;br /&gt;    欧美大片想让字幕默认eng，可惜 --default-track 设置后 Windows Kmplayer 还是默认中文chs，&lt;br /&gt;按照 chs eng 字母顺序来，google 说有些视频播放器 ignore default flag。&lt;br /&gt;&lt;br /&gt;普通话国产电影，去掉所有字幕:&lt;br /&gt;$ mkvmerge -S 霸王别姬.1993.mkv -o 霸王别姬.1993.out.mkv&lt;br /&gt;&lt;br /&gt;从mkv提取字幕:&lt;br /&gt;&lt;br /&gt;$ mplayer -v foo.mkv    发现是英简繁三种字幕&lt;br /&gt;$ mkvmerge -i foo.mkv &lt;br /&gt;File 'foo.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_AAC)&lt;br /&gt;Track ID 3: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 4: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 5: subtitles (S_TEXT/UTF8)&lt;br /&gt;&lt;br /&gt;$ mkvextract tracks foo.mkv 3:3.srt 4:4.srt 5:5.srt&lt;br /&gt;&lt;br /&gt;生成的文件为utf8编码，中文没有乱码，完全正常。&lt;br /&gt;&lt;br /&gt;提取《大话西游之仙履奇缘》的两条音轨:&lt;br /&gt;$ ffmpeg -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv&lt;br /&gt;Input #0, matroska, from 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv':&lt;br /&gt;  Metadata:&lt;br /&gt;    doctype         : matroska&lt;br /&gt;  Duration: 01:39:44.06, start: 0.000000, bitrate: 640 kb/s&lt;br /&gt;    Stream #0.0(chi): Video: h264, yuv420p, 1280x720, PAR 1:1 DAR 16:9, 24 fps, 24 tbr, 1k tbn, 48 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : A.Chinese.Odyssey.Part.Two.Cinderella.1994.x264.720p.2AUDiO.DTS.AC3.BDRiP-CHD&lt;br /&gt;    Stream #0.1(chi): Audio: dca, 48000 Hz, 6 channels, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Cantonese, DTS 5.1 @ 768Kbps&lt;br /&gt;    Stream #0.2(chi): Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Mandarin, AC3 5.1 @ 640Kbps&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv &lt;br /&gt;File 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_DTS)&lt;br /&gt;Track ID 3: audio (A_AC3)&lt;br /&gt;$ sudo mkvextract tracks A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv 2:Cantonese.dts 3:Mandarin.ac3&lt;br /&gt;&lt;br /&gt;如果mount上一个Windows硬盘，把生成的字幕文件放在Windows上，由于换行符的差别，生成的文件在 Windows&lt;br /&gt; 上，整个文件就是一行。而在 linux 下对 Windows 上的 3.srt 执行 $ sudo unix2dos 3.srt  会报错。 &lt;br /&gt;因此要把生成的 3.srt 4.srt 5.srt 放在 Linux 上，执行 $ unix2dos 3.srt 4.srt 5.srt 后再放到Windows&lt;br /&gt;上。 往视频里封装srt字幕:&lt;br /&gt;&lt;br /&gt;软字幕，过后还可以extract、delete。man mkvmerge 末尾有example，中文字幕要存为 utf-8 。&lt;br /&gt;&lt;br /&gt;封装单个字幕:&lt;br /&gt;$ mkvmerge 新上海滩.1996.avi --language 0:chi 新上海滩.1996.chs.srt -o 新上海滩.1996.mkv&lt;br /&gt;&lt;br /&gt;封装多个字幕:&lt;br /&gt;$ mkvmerge foo.avi --language 0:chi foo.chs.srt --language 0:eng foo.eng.srt -o out.mkv&lt;br /&gt;&lt;br /&gt;subtitleeditor 处理字幕文件:&lt;br /&gt;$ sudo yum install subtitleeditor&lt;br /&gt;&lt;br /&gt;调节固定秒数:&lt;br /&gt;打开subtitleeditor，File --&amp;gt; Open sub 后，Ctrl+a全选，Timings --&amp;gt; Add 100 Milliseconds&lt;br /&gt;反操作就是下面的 Remove 100 Milliseconds&lt;br /&gt;如果整体调节50ms就选 Timings -&gt; Move Subtitles  自己填数字&lt;br /&gt;&lt;br /&gt;2. 处理 mp4 用 MP4Box，它隶属于 qpac&lt;br /&gt;$ sudo yum install qpac&lt;br /&gt;$ man mp4box    注意命令是 MP4Box，不是 mp4box&lt;br /&gt;&lt;br /&gt;生成mp4:&lt;br /&gt;$ MP4Box -add in.avi out.mp4&lt;br /&gt;$ file out.mp4 &lt;br /&gt;out.mp4: ISO Media, MPEG v4 system, version 1&lt;br /&gt;&lt;br /&gt;截一段mp4:&lt;br /&gt;$ MP4Box -add in.mp4 out.mp4 -splitx 60:186&lt;br /&gt;&lt;br /&gt;合并mp4:&lt;br /&gt;$ MP4Box -cat 1.mp4 -cat 2.mp4 out.mp4&lt;br /&gt;&lt;br /&gt;内嵌字幕生成mp4:  一个avi、srt，将srt嵌入到avi中，无法提取&lt;br /&gt;$ MP4Box -add "中国残留孤儿归国记.avi" -add "中国残留孤儿归国记.srt" "中国残留孤儿归国记.mp4"&lt;br /&gt;&lt;br /&gt;3. 上面两个不行了再考虑用ffmpeg，ffmpeg 不行了用mencoder。&lt;br /&gt;   比如 .wmv .mpg .flv 上面两个工具都不认、codec 转换。man ffmpeg、man mencoder&lt;br /&gt;   ffmpeg、mencoder 参数顺序很重要。&lt;br /&gt;&lt;br /&gt;截一段avi出来: vcodec 不变&lt;br /&gt;$ ffmpeg -ss 01:05:08 -t 600 -i in.avi -vcodec copy -acodec copy -o out.avi&lt;br /&gt;有时ffmpeg 截取的开始时间不准，就用 mencoder:&lt;br /&gt;$ mencoder in.avi -ovc copy -oac copy -ss 01:05:08 -endpos 600 -o out.avi&lt;br /&gt;&lt;br /&gt;有一个1080P的h264视频，太大，降成720P:&lt;br /&gt;$ ffmpeg -i "世界自然遺產.Asia II.ts" -vcodec mpeg4 -b 4000k -maxrate 4200k -bufsize 1000k&lt;br /&gt;  -r 59.96 -s hd720 -aspect 16:9 -acodec copy -f matraska "世界自然遺產.Asia II.mkv"&lt;br /&gt;&lt;br /&gt;wmv to avi: 只转换vcodec，其它参数尽量不变，ffmpeg -i 看wmv参数&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv &lt;br /&gt;......&lt;br /&gt;  Duration: 02:31:53.32, start: 2.000000, bitrate: 560 kb/s&lt;br /&gt;    Stream #0.0: Audio: wmav2, 44100 Hz, 2 channels, s16, 64 kb/s&lt;br /&gt;    Stream #0.1: Video: wmv3, yuv420p, 640x480, 30 tbr, 1k tbn, 1k tbc&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv -vcodec mpeg4 -b 560k -maxrate 660k -bufsize 1000k -r 30&lt;br /&gt;  -acodec libmp3lame -ab 64k -ac 2 -f avi 打开记忆.avi&lt;br /&gt;&lt;br /&gt;直接 -acodec copy 没有声音，ffmpeg 处理 acodec wmav2 有问题。&lt;br /&gt;mp3 bitrate 不要小于64k，否则声音失真;&lt;br /&gt;&lt;br /&gt;将两条ac3音轨完整提取出来，ffmpeg 多音轨用 -map:&lt;br /&gt;$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv&lt;br /&gt;......&lt;br /&gt;  Duration: 01:44:00.25, start: 0.000000, bitrate: 1280 kb/s&lt;br /&gt;    Stream #0.0(eng): Video: h264, yuv420p, 1280x536, PAR 1:1 DAR 160:67, 23.98 fps, 24 tbr, 1k tbn, 47.95 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s &lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s &lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv&lt;br /&gt;  -map 0:1 -acodec copy japanese.ac3 -map 0:2 -acodec copy france.ac3&lt;br /&gt;&lt;br /&gt;0:1 0:2 就是 Stream #0.1  Stream #0.2，ffmpeg用map称呼又用冒号就很容易引起歧义。见过的视频都是&lt;br /&gt;一个video stream，mkvmerge 就 1、2、3、4 顺序叫TID，非常清晰，不知道ffmpeg出于什么考虑。&lt;br /&gt;&lt;br /&gt;目标硬盘是mount上的NTFS，结果提取一段时间报错，不让同时write，同时 mount 假死，中断操作后，&lt;br /&gt;mount 立刻恢复了。把目标ac3 同时 write 到本机目录就不影响mount了。&lt;br /&gt;&lt;br /&gt;从视频中提取mp3:&lt;br /&gt;$ ffmpeg -ss 00:00:00 -t 286 -i 日本通商的150年.avi -vn -acodec copy "加古隆 - JAPANデビュー.mp3"&lt;br /&gt;&lt;br /&gt;$ mencoder 日本通商的150年.avi -ovc copy -oac mp3lame -lameopts cbr:br=128:aq=0:mode=2&lt;br /&gt;  -of rawaudio -o "加古隆 - JAPANデビュー.mp3" -ss 00:00:00 -endpos 286&lt;br /&gt;&lt;br /&gt;从 wmv 提取音频:&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv -vn -acodec copy -f asf 打开记忆.wma&lt;br /&gt;&lt;br /&gt;多音轨视频 VTS_01_7.vob，改变其音频参数，同时不丢失音轨:&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;-ac 5.1，现设定 -ac 2&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;加 -map 时位置很重要，下面的方式虽然也行但会损失音质:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2  &lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob -newaudio&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:03:15.89, start: 0.500000, bitrate: 6900 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x1c0]: Audio: mp2, 48000 Hz, 2 channels, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;audio 0.2 变成 mp2 了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ac3 aac wma mp3 互转:  lame 不认 wma&lt;br /&gt;$ ffmpeg -i 打开记忆.wma -vn -f mp3 打开记忆.mp3&lt;br /&gt;$ ffmpeg -i 打开记忆.mp3 -vn -f asf 打开记忆.wma&lt;br /&gt;$ ffmpeg -i 阿里山.ac3 -vn -acodec libmp3lame -ab 320k -ac 2 -f mp3 阿里山.mp3&lt;br /&gt;ac3 to mp3  要指定 -ac，虽然默认是1，但不指定不行，是个bug&lt;br /&gt;&lt;br /&gt;$ ffmpeg -formats|less    发现 ffmpeg 无法生成ape，生成ape用mac&lt;br /&gt;&lt;br /&gt;wav to ape: &lt;br /&gt;$ mac foo.wav foo.ape -c4000&lt;br /&gt;&lt;br /&gt;wv to wav: &lt;br /&gt;$ sox Kill.Bill.Vol.1.wv Kill.Bill.Vol.1.wav&lt;br /&gt;&lt;br /&gt;wav ape flac 互转:&lt;br /&gt;$ ffmpeg -i "酒井法子 - 碧いうさぎ.wav" -vn -f flac "酒井法子 - 碧いうさぎ.flac"&lt;br /&gt;&lt;br /&gt;截取[mp3|wav|flac]:&lt;br /&gt;$ ffmpeg -ss 00:02:05 -t 300 -i 打开记忆.mp3 -vn -acodec copy cut.mp3&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;合并视频:&lt;br /&gt;&lt;br /&gt;先用cat，mkvmerge、mp4box，要注意的是 ffmpeg 不能合并，要用 mencoder。&lt;br /&gt;$ cat 1.avi 2.avi 3.avi &amp;gt;&amp;gt; 1987红楼梦.avi&lt;br /&gt;$ cat 龙应台-01.mp3 龙应台-02.mp3 龙应台对话.mp3 &amp;gt;&amp;gt; 龍應台.北大.從鄉愁到美麗島.73min.24s.2010.08.01.mp3&lt;br /&gt;&lt;br /&gt;cat 有些avi可以，比如一个 DVD iso 种各个vob参数都一样，就可以直接用cat，但多数format都不能用cat，&lt;br /&gt;rm、mkv、mp4 从来没cat成功过。cat 成功与否和format关系很大，没发现和codec有关，avi h264一样合并&lt;br /&gt;成功过。&lt;br /&gt;&lt;br /&gt;$ cat 史上最牛50进球.avi 十大门将愚蠢失误.avi &amp;gt;&amp;gt; temp.avi&lt;br /&gt;生成的temp.avi合并成功了，但无法前后拖动，用mencoder -forceidx 加上 idx 就好了&lt;br /&gt;$ mencoder temp.avi -ovc copy -oac copy -forceidx -o out.avi&lt;br /&gt;&lt;br /&gt;如果mount一个Windows NTFS，想把cat生成的文件放在Windows机器上，那要用root执行，sudo 不行:&lt;br /&gt;$ sudo cat 1.avi 2.avi &amp;gt;&amp;gt; /mnt/win/out.avi&lt;br /&gt;bash: out.avi: Permission denied&lt;br /&gt;&lt;br /&gt;sudo 只对cat起作用，cat 操作升级为root，然后bash 负责 &amp;gt;&amp;gt; 操作，bash 没有被sudo提升权限。&lt;br /&gt;sudo 涉及redirection时，用 bash -c 或 tee&lt;br /&gt;$ sudo bash -c 'cat VTS_01_7.vob "孙燕姿 - 遇见.vob" &gt;&gt; /mnt/win/out.avi'&lt;br /&gt;$ cat VTS_01_7.vob "孙燕姿 - 遇见.vob" | sudo tee /mnt/win/out.avi&lt;br /&gt;看到 pipe | 不禁想到了上ftp站点在线看电影:&lt;br /&gt;$ lftp web:123@*.*.*.*&lt;br /&gt;&amp;gt; cat 日俄战争.mp4 |mplayer -&lt;br /&gt;&lt;br /&gt;一个双音轨的 DVD 文件 a.iso，把里面的文件合并成一个:&lt;br /&gt;$ sudo mount ~/a.iso /mnt/temp -o loop&lt;br /&gt;$ ls -lR /mnt/temp&lt;br /&gt;/mnt/temp:&lt;br /&gt;total 4&lt;br /&gt;dr-xr-xr-x 2 4294967295 4294967295  40 2009-05-30 19:11 AUDIO_TS&lt;br /&gt;dr-xr-xr-x 2 4294967295 4294967295 456 2009-05-30 19:11 VIDEO_TS&lt;br /&gt;&lt;br /&gt;/mnt/temp/AUDIO_TS:&lt;br /&gt;total 0&lt;br /&gt;&lt;br /&gt;/mnt/temp/VIDEO_TS:&lt;br /&gt;total 2454804&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295       8192 2009-05-30 18:41 VIDEO_TS.BUP&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295       8192 2009-05-30 18:41 VIDEO_TS.IFO&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295     133120 2009-05-30 19:11 VTS_01_0.BUP&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295     133120 2009-05-30 18:41 VTS_01_0.IFO&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295   39340032 2009-05-30 19:11 VTS_01_0.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_1.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_2.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295  326965248 2009-05-30 19:11 VTS_01_3.VOB&lt;br /&gt;&lt;br /&gt;$ cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB &amp;gt;&amp;gt; out.vob&lt;br /&gt;OK了，out.vob 保持多音轨。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;西游记前25集，6张 DVD .iso 文件，国粤双语，每个 .iso 里有4集，用电脑看不方便，想单独提取出来。&lt;br /&gt;发现.iso中每一集都分为两个vob，就先合并，然后抛弃粤语音轨。&lt;br /&gt;.iso 在Windows上，直接 cat 不行，要用 bash -c&lt;br /&gt;&lt;br /&gt;$ sudo bash -c "cat VTS_01_1.VOB VTS_01_2.VOB &amp;gt;&amp;gt; 18.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_02_1.VOB VTS_02_2.VOB &amp;gt;&amp;gt; 19.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_03_1.VOB VTS_03_2.VOB &amp;gt;&amp;gt; 20.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_04_1.VOB VTS_04_2.VOB &amp;gt;&amp;gt; 21.mkv"&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge 18.vob -o 18.mkv&lt;br /&gt;$ sudo mkvmerge 19.vob -o 19.mkv&lt;br /&gt;$ sudo mkvmerge 20.vob -o 20.mkv&lt;br /&gt;$ sudo mkvmerge 21.vob -o 21.mkv&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记18.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记19.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记20.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记21.mkv&lt;br /&gt;&lt;br /&gt;由于同时开的mkvmerge太多，频繁写入硬盘，使得4个对应mkvmerge的进程都处于了D状态:&lt;br /&gt;&lt;br /&gt;$ top&lt;br /&gt;&lt;br /&gt;  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                              &lt;br /&gt; 1087 root      20   0     0    0    0 S  7.0  0.0  25:42.83 cifsd                                                &lt;br /&gt; 1121 root      20   0 90852  22m 9284 S  1.7  2.3  85:36.64 Xorg                                                 &lt;br /&gt;22116 cngrid    20   0 65308  18m  12m S  1.3  1.8   1:06.17 gnome-terminal                                       &lt;br /&gt;25334 root      20   0 38012 9268 2260 D  0.7  0.9   0:49.12 mkvmerge                                             &lt;br /&gt;25380 root      20   0 38300  10m 3456 D  0.7  1.1   0:48.66 mkvmerge                                             &lt;br /&gt;25424 root      20   0 37768 9024 2260 D  0.7  0.9   0:48.24 mkvmerge                                             &lt;br /&gt;25429 root      20   0 37296  10m 2372 D  0.7  1.0   0:57.04 mkvmerge             &lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;man top 说是 uninterruptible sleep，但进程仍旧继续执行，视频转换进度在不断增加。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;合并mpg:&lt;br /&gt;&lt;br /&gt;$ file *.mpg&lt;br /&gt;寻找.2004.上.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;寻找.2004.下.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 寻找.2004.上.mpg&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from '寻找.2004.上.mpg':&lt;br /&gt;  Duration: 01:07:03.01, start: 0.351433, bitrate: 1410 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x288 [PAR 178:163 DAR 1958:1467], 1150 kb/s, 25 fps, 25 tbr, 90k tbn, 25 tbc&lt;br /&gt;    Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, 2 channels, s16, 224 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 寻找.2004.上.mpg&lt;br /&gt;File '寻找.2004.上.mpg': unsupported container: RIFF CDXA&lt;br /&gt;&lt;br /&gt;mkvmerge 不认&lt;br /&gt;&lt;br /&gt;$ MP4Box -cat 寻找.2004.上.mpg -cat 寻找.2004.下.mpg 寻找.2004.mp4&lt;br /&gt;&lt;br /&gt;成功合并，bitrate 保持的很好。用mencoder也成功了，bitrate 保持的都很好:&lt;br /&gt;&lt;br /&gt;$ mencoder 寻找.2004.上.mpg 寻找.2004.下.mpg -ovc copy -oac copy&lt;br /&gt;  -of mpeg -mpegopts format=mpeg1 -o out.mpg&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;to dvd:&lt;br /&gt;$ ffmpeg -i foo.avi -target dvd out.vob&lt;br /&gt;&lt;br /&gt;to psp:&lt;br /&gt;$ ffmpeg -i foo.avi -r 29.97 -b 564k -ar 24000 -ab 64k -s 368x208 -f psp out.mp4&lt;br /&gt;&lt;br /&gt;有时生成的文件播放时图像变窄或变宽，即 Display Aspect Ratio 失调，可以用 -aspect 指定。&lt;br /&gt;&lt;br /&gt;从视频截取图片，1 fps:&lt;br /&gt;$ ffmpeg -i foo.avi -r 1 -f image2 foo-%04d.jpeg&lt;br /&gt;&lt;br /&gt;将一堆图片合成avi，0.5 fps:    如果图片名不规律就用mencoder&lt;br /&gt;$ ls|grep .png$ &amp;gt;&amp;gt; list&lt;br /&gt;$ mencoder mf://@list -mf type=png -ovc lavc -lavcopts mbd=2:trell -fps 0.5 -o out.avi&lt;br /&gt;&lt;br /&gt;1.  合并两个rm: 只为管理方便，其它参数不动&lt;br /&gt;    合并成mkv，由于ffmpeg 把视频转化成 mkv 后，file 无法识别format，还是用 mkvmerge。&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 38度線A.rmvb &lt;br /&gt;File '38度線A.rmvb': container: RealMedia&lt;br /&gt;Track ID 0: audio (cook)&lt;br /&gt;Track ID 1: video (RV40)&lt;br /&gt;&lt;br /&gt;$ mkvmerge 38度線A.rmvb -o 38度線A.mkv &lt;br /&gt;$ mkvmerge -i 38度線A.mkv&lt;br /&gt;File '38度線A.mkv': container: Matroska&lt;br /&gt;Track ID 1: audio (A_REAL/COOK)&lt;br /&gt;Track ID 2: video (V_REAL/RV40)&lt;br /&gt;&lt;br /&gt;Windows下Kmplayer播放 38度線A.mkv 只有图像没有声音，mkvmerge 对 acodec cook 没处理好。&lt;br /&gt;用 ffmpeg 把audio提取出来转化成mp3，然后用mkvmerge封装mp3:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 38度線A.rmvb -vn -acodec libmp3lame -ab 128k 38度線A.mp3&lt;br /&gt;$ mkvmerge -A 38度線A.rmvb 38度線A.mp3 -o 38度線A.mkv&lt;br /&gt;&lt;br /&gt;可以了。38度線B.rmvb -&amp;gt; 38度線B.mkv&lt;br /&gt;$ mkvmerge 38度線A.mkv + 38度線B.mkv -o 38度線.2002.160min.mkv&lt;br /&gt;$ mkvmerge -i 38度線.2002.160min.mkv &lt;br /&gt;File '38度線.2002.160min.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_REAL/RV40)&lt;br /&gt;Track ID 2: audio (A_MPEG/L3)&lt;br /&gt;&lt;br /&gt;可见，acodec 变成mp3了，但 vcodec 仍是real，也就是说，要想看这个mkv文件，仍需要有real decodec。&lt;br /&gt;这个例子也说明一个视频的扩展名、format只是形式，codec才是关键。 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;再合并两个rm:  辛亥双十.1.rmvb   辛亥双十.2.rmvb &lt;br /&gt;&lt;br /&gt;和上面一样，先提取出mp3，再合并。但 辛亥双十.2.rmvb 质量不行，无法用 mkvmerge直接转换成mkv:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -A 辛亥双十.2.rmvb 辛亥双十.2.mp3 -o 辛亥双十.2.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'辛亥双十.2.rmvb': Using the RealMedia demultiplexer.&lt;br /&gt;'辛亥双十.2.mp3': Using the MP2/MP3 demultiplexer.&lt;br /&gt;Warning: '辛亥双十.2.mp3': Skipping 33 bytes at the beginning (no valid MP3 header found).&lt;br /&gt;'辛亥双十.2.rmvb' track 1: Using the video output module (FourCC: RV40).&lt;br /&gt;'辛亥双十.2.mp3' track 0: Using the MPEG audio output module.&lt;br /&gt;The file '辛亥双十.2.mkv' has been opened for writing.&lt;br /&gt;Warning: '辛亥双十.2.rmvb': File contains fewer frames than expected or is corrupt after frame 46566.&lt;br /&gt;Progress: 100%&lt;br /&gt;The cue entries (the index) are being written...&lt;br /&gt;Muxing took 43 seconds.&lt;br /&gt;&lt;br /&gt;没有转换完全，Warning 说有frame corrupt。用 ffmpeg 把vcodec转化为 mpeg4 试试:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 辛亥双十.2.rmvb -vcodec mpeg4 -b 600k -acodec libmp3lame -ab 96k -ac 2 &lt;br /&gt;  -s 352x240 -r 12 辛亥双十.2.avi&lt;br /&gt;&lt;br /&gt;转换过程中 drop 很多frame，导致生成的avi audio/video 不同步，要先做同步:&lt;br /&gt;Windows 用Kmplayer 可以调整: 播放 -&amp;gt; 音频/视频同步 -&amp;gt; 重新同步音频 - 0.5 秒，试几下就行了。&lt;br /&gt;&lt;br /&gt;mplayer -delay 也可以找到所需同步时间，一点一点尝试&lt;br /&gt;$ mplayer -delay 1 辛亥双十.2.avi&lt;br /&gt;$ mplayer -delay 2 辛亥双十.2.avi&lt;br /&gt;$ mplayer -delay 3 辛亥双十.2.avi&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;但经过验证，-delay 的时间只是估计值，还要经过1、2秒钟的调整才行，最后找到audio需要延迟4500ms&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge -i 辛亥双十.2.avi&lt;br /&gt;File '辛亥双十.2.avi': container: AVI&lt;br /&gt;Track ID 0: video (FMP4)&lt;br /&gt;Track ID 1: audio (MP3)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -y 1:4500 辛亥双十.2.avi -o 辛亥双十.2.mkv&lt;br /&gt;&lt;br /&gt;同样，辛亥双十.1.rmvb 也要转换为 MPEG-4/mp3/辛亥双十.1.avi，然后 mkvmerge 成 辛亥双十.1.mkv。&lt;br /&gt;&lt;br /&gt;$ mkvmerge 辛亥双十.1.mkv + 辛亥双十.2.mkv -o 辛亥双十.1981.120min.mkv&lt;br /&gt;&lt;br /&gt;合并成功了。网上有个 x264 版本，也是460MB左右，H.264 比 MPEG-4 高效，就不共享这个了。&lt;br /&gt;&lt;br /&gt;经验就是: 压片时最好别压成 .rm  .wmv，自身质量很一般，想进行合并操作太麻烦了。&lt;br /&gt;即使压成 .rm，codec 也别用 RV40 + Cook，drop frame 太多了&lt;br /&gt;即使压成 .wmv，codec 也别用  wmv + wma&lt;br /&gt;推荐用 MPEG-4 + mp3，或者 H.264 + mp3&lt;br /&gt;&lt;br /&gt;2. 合并7个flv: 参数类型都相同，文件很小，都在5MB左右&lt;br /&gt;$ file *.flv&lt;br /&gt;01.flv: Macromedia Flash Video&lt;br /&gt;02.flv: Macromedia Flash Video&lt;br /&gt;......&lt;br /&gt;07.flv: Macromedia Flash Video&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 01.flv&lt;br /&gt;......&lt;br /&gt;  Duration: 00:05:53.55, start: 0.000000, bitrate: 113 kb/s&lt;br /&gt;    Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 49 kb/s, 18 tbr, 1k tbn, 36 tbc&lt;br /&gt;    Stream #0.1: Audio: aac, 22050 Hz, stereo, s16, 64 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;cat不行，mkvmerge、MP4Box 不认，先用ffmpeg转成mp4，然后用MP4Box合并:&lt;br /&gt;$ ffmpeg -i 01.flv -vcodec libx264 -vpre normal -b 49k -acodec aac -strict experimental&lt;br /&gt;  -ab 64k -ac 2 -ar 22050 -s 320x240 -r 18 01.mp4&lt;br /&gt;&lt;br /&gt;$ MP4Box -cat 01.mp4 -cat 02.mp4 -cat 03.mp4 -cat 04.mp4 -cat 05.mp4 -cat 06.mp4 -cat 07.mp4 out.mp4&lt;br /&gt;&lt;br /&gt;3. 合并两个多音轨的vob:&lt;br /&gt;&lt;br /&gt;$ file "孙燕姿 - 遇见.vob" VTS_01_7.vob &lt;br /&gt;孙燕姿 - 遇见.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;VTS_01_7.vob:      MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i "孙燕姿 - 遇见.vob" -i VTS_01_7.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from '孙燕姿 - 遇见.vob':&lt;br /&gt;  Duration: 00:03:40.86, start: 786.008633, bitrate: 5120 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4225 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;[mpeg2video @ 0x918c3a0]mpeg_decode_postinit() failure&lt;br /&gt;[mpeg @ 0x918b070]max_analyze_duration reached&lt;br /&gt;Input #1, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #1.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #1.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;两个视频vcodec都是MPEG-2，都是双音轨，acodec 都是ac3。似乎一致，看能否合并:&lt;br /&gt;&lt;br /&gt;$ mkvmerge  "孙燕姿 - 遇见.vob" + VTS_01_7.vob -o out.vob&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'孙燕姿 - 遇见.vob': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_7.vob': Using the MPEG PS demultiplexer.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 1: Using the AC3 output module.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 2: Using the AC3 output module.&lt;br /&gt;'VTS_01_7.vob' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'VTS_01_7.vob' track 1: Using the AC3 output module.&lt;br /&gt;'VTS_01_7.vob' track 2: Using the AC3 output module.&lt;br /&gt;No append mapping was given for the file no. 1 ('VTS_01_7.vob'). A default mapping of 1:0:0:0,1:1:0:1,1:2:0:2 will be used instead. Please keep that in mind if mkvmerge aborts with an error message regarding invalid '--append-to' options.&lt;br /&gt;Error: The track number 1 from the file 'VTS_01_7.vob' cannot be appended to the track number 1 from the file '孙燕姿 - 遇见.vob'. The track parameters do not match.&lt;br /&gt;&lt;br /&gt;无法合并，Error 说两个视频的第一条音轨的参数不同，回头细看真是不同: 一个是 stereo，另一个是 5.1。&lt;br /&gt;把 VTS_01_7.vob 的audio channel 数目降成2个再合并:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -vcodec copy -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;&lt;br /&gt;VTS.vob 只有第一条音轨，另一条丢失。&lt;br /&gt;&lt;br /&gt;$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.vob&lt;br /&gt;&lt;br /&gt;合并成功了。&lt;br /&gt;$ ffmpeg -i &lt;br /&gt;  Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s&lt;br /&gt;    Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;final.vob中，前段 "孙燕姿 - 遇见.vob" 两条音轨都有，后段 VTS.vob 也被添加了一条没有声音的新音轨。&lt;br /&gt;vbitrate 取低的192k。不足之处是前段画面的长宽变化了，后段正常。看各自的 Display Aspect Ratio，&lt;br /&gt;即DAR，分别是 16:9 和 4:3 ，一个视频的 aspect ratio 只有一个，只能将就点了。&lt;br /&gt;&lt;br /&gt;若想保持 VTS_01_7.vob 的2条音轨就用map:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;参数保持的很好，合并:&lt;br /&gt;$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.mkv&lt;br /&gt;$ ffmpeg -i final.mkv&lt;br /&gt;......&lt;br /&gt;Input #0, matroska, from 'final.mkv':&lt;br /&gt;  Metadata:&lt;br /&gt;    doctype         : matroska&lt;br /&gt;  Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s&lt;br /&gt;    Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;成功了，播放正常，音轨切换也正常，想保持vob format就用mencoder。&lt;br /&gt;&lt;br /&gt;再看一个audio:&lt;br /&gt;&lt;br /&gt;$ file Eagles.Hotel.California.Original.1994.Live.vob &lt;br /&gt;Eagles.Hotel.California.Original.1994.Live.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':&lt;br /&gt;  Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s&lt;br /&gt;    Stream #0.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s&lt;br /&gt;    Stream #0.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;第一条音轨无法播放，把后两条音轨提取出来，其中0.2显示dca的不认识，先用.wav代替:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob -vn -map 0:2 -acodec copy 02.wav&lt;br /&gt;  -map 0:3 -acodec copy 03.ac3&lt;br /&gt;&lt;br /&gt;$ file 02.wav 03.ac3 &lt;br /&gt;02.wav: RIFF (little-endian) data, WAVE audio, 6 channels 48000 Hz&lt;br /&gt;03.ac3: Sendmail frozen configuration  - version \304\024\320\274*$nG\273\257\221\213\020\0256\346XQ\273&lt;br /&gt;&lt;br /&gt;两个文件 Windows 千千都能正常播放，google 知道dca就是decoding dts 的，libdca是开源的，&lt;br /&gt;$ locate libdca   可以找到 .so&lt;br /&gt;&lt;br /&gt;发现 VTS_01_7.vob 和 Eagles.Hotel.California.Original.1994.Live.vob 都有一条 ac3 5.1 audio，&lt;br /&gt;现把它们合并，最终视频只有 ac3 5.1 这一条音轨:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -i Eagles.Hotel.California.Original.1994.Live.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;[mpeg @ 0x96ee4e0]max_analyze_duration reached&lt;br /&gt;Input #1, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':&lt;br /&gt;  Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s&lt;br /&gt;    Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #1.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s&lt;br /&gt;    Stream #1.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s&lt;br /&gt;    Stream #1.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i VTS_01_7.vob&lt;br /&gt;File 'VTS_01_7.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i Eagles.Hotel.California.Original.1994.Live.vob &lt;br /&gt;File 'Eagles.Hotel.California.Original.1994.Live.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (DTS)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 2 VTS_01_7.vob -a 1 Eagles.Hotel.California.Original.1994.Live.vob -o out.mkv&lt;br /&gt;合并失败，用 mencoder:&lt;br /&gt;&lt;br /&gt;$ mplayer -v  找到对应的 audio number 分别为 128、129&lt;br /&gt;$ mencoder VTS_01_7.vob -aid 128 Eagles.Hotel.California.Original.1994.Live.vob -aid 129&lt;br /&gt;  -ovc copy -oac copy -of mpeg -mpegopts format=dvd -o out.vob&lt;br /&gt;&lt;br /&gt;合并成功，播放正常，原来两个视频的DAR就不同，所以会有一个视频长宽比例失调，可以用 -aspect 指定。&lt;br /&gt;参数也正常:&lt;br /&gt;&lt;br /&gt;$ file out.vob&lt;br /&gt;out.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i out.vob&lt;br /&gt;Input #0, mpeg, from 'out.vob':&lt;br /&gt;  Duration: 00:11:58.41, start: 0.233367, bitrate: 5201 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;继续尝试把 ac3 5.1 和 dts 5.1 合并，没成功。对于两个不同的codec，合并不成功很正常。&lt;br /&gt;&lt;br /&gt;4.《让子弹飞》是个双音轨的 DVD 一共7个vob，两条音轨都是国语，都有 A/V 不同步的现象，而且每个vob&lt;br /&gt; A/V 不同步程度还不同，有的差1s，有的差0.5s。现在把片源 A/V 同步，都是普通话，只留一个音轨，合并&lt;br /&gt; 成一个普通视频文件。先分别把vob转化成mkv，然后合并:&lt;br /&gt;$ mkvmerge -i VTS_01_1.VOB&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;mplayer -delay 分别试试就可以知道延迟的秒数:&lt;br /&gt;$ mplayer -delay 0.5 VTS_01_1.VOB  &lt;br /&gt;$ mplayer -delay 1 VTS_01_1.VOB    &lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:800 VTS_01_1.VOB -o out1.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'VTS_01_1.VOB': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_1.VOB': Processing the following files as well: VTS_01_2.VOB, VTS_01_3.VOB, VTS_01_4.VOB, VTS_01_5.VOB, VTS_01_6.VOB, VTS_01_7.VOB&lt;br /&gt;'VTS_01_1.VOB' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'VTS_01_1.VOB' track 1: Using the AC3 output module.&lt;br /&gt;The file 'out1.mkv' has been opened for writing.&lt;br /&gt;Progress: 1%&lt;br /&gt;&lt;br /&gt;由shell信息知道 mkvmerge 想把这7个VOB一起处理，在这是不行的，因为每个VOB A/V 延迟秒数不同，&lt;br /&gt;所以先中断进程。建个文件夹，把其它6个VOB放进去，一个一个的分别处理:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:1000 VTS_01_1.VOB -o out1.mkv&lt;br /&gt;&lt;br /&gt;out1.mkv 比 VTS_01_1.VOB 小了30MB，小于1GB，可以分别把生成的7个mkv文件放115上给别人共享了：）&lt;br /&gt;网上一个视频如果是双语的，只要不超过1030MB 就确定可以下来，只保留一条原声，转换后就小于1GB了。&lt;br /&gt;&lt;br /&gt;其它6个VOB类似处理，每个vob的同步时间的调整都要尽量精确，因为一旦错了一个，后面的都会跟着错。可&lt;br /&gt;以在处理完前3个VOB之后，合并一下看看效果，如果不行就重新调教时间，提前发现问题。依次调教的秒数:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_2.VOB -o out2.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_3.VOB -o out3.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_4.VOB -o out4.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:100 VTS_01_5.VOB -o out5.mkv&lt;br /&gt;$ mkvmerge -a 1 VTS_01_7.VOB -o out7.mkv&lt;br /&gt;&lt;br /&gt;其中 VTS_01_6.VOB 无法处理&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_6.VOB -o out6.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'VTS_01_6.VOB': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_6.VOB' track 0: Using the MPEG-4 part 10 ES video output module.&lt;br /&gt;'VTS_01_6.VOB' track 1: Using the AC3 output module.&lt;br /&gt;The file 'out6.mkv' has been opened for writing.&lt;br /&gt;Warning: 'VTS_01_6.VOB' track 1: This AC3 track contains 1155 bytes of non-AC3 data which were skipped. The audio/video synchronization may have been lost.&lt;br /&gt;Error: 'VTS_01_6.VOB' track 0: mkvmerge encountered broken or unparsable data in this AVC/h.264 video track. Either your file is damaged (which mkvmerge cannot cope with yet) or this is a bug in mkvmerge itself. The error message was:&lt;br /&gt;end-of-file&lt;br /&gt;&lt;br /&gt;处理前5个VOB时也会有那个Warning，但是没有Error，始终能继续处理，看下 VTS_01_6.VOB 确实和别的不同:&lt;br /&gt;$ mkvmerge -i VTS_01_6.VOB &lt;br /&gt;File 'VTS_01_6.VOB': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (AVC/h.264)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;video那行显示是 AVC/h.264，ffmpeg -i 显示是MPEG-2，Windows Kmplayer 也显示是 MPEG-2。&lt;br /&gt;用 ffmpeg 转化成 dvd format 看能否修复这个VOB:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_6.VOB':&lt;br /&gt;  Duration: 00:20:35.93, start: 6180.812544, bitrate: 6949 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 33.01 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;音轨只要第一条&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -target dvd mid.vob&lt;br /&gt;$ mkvmerge -i mid.vob  发现没修复过来，又试几个参数都不行:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -f dvd mid.vob&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:2 ......&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;只好 mencoder 试试:&lt;br /&gt;$ mplayer -v VTS_01_6.VOB     找到 -aid audio number，要第一条音轨 -aid 128&lt;br /&gt;$ mencoder VTS_01_6.VOB -ovc copy -oac copy -aid 128 -of mpeg -mpegopts format=dvd -o mid.vob&lt;br /&gt;$ mkvmerge -i mid.vob&lt;br /&gt;File 'mid.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;&lt;br /&gt;正确识别为 MPEG-2 了，ffmpeg -i 发现码率保持的也很好。&lt;br /&gt;&lt;br /&gt;$ mkvmerge -y 0:1150 mid.vob -o out6.mkv&lt;br /&gt;$ mkvmerge out1.mkv + out2.mkv + out3.mkv + out4.mkv + out5.mkv + out6.mkv + out7.mkv &lt;br /&gt;  -o 让子弹飞.2010.mkv&lt;br /&gt;&lt;br /&gt;终于得到 vcodec MPEG-2，vbitrate 6 Mbps 6GB 让子弹飞.2010.mkv 了! &lt;br /&gt;&lt;br /&gt;《二百三高地》的DVD映像 .iso 中的 VTS_01_1.VOB 在播放时没有idx，无法拖动进度，有的 VOB 在播放时&lt;br /&gt;进度突然向前跳跃一大截，用上面的方法 mencoder 也可以修复:&lt;br /&gt;&lt;br /&gt;$ mencoder VTS_01_1.VOB -ovc copy -oac copy -of mpeg -mpegopts format=dvd -o out.vob&lt;br /&gt;&lt;br /&gt;可以拖动了，播放也正常，进度也不会突然跳跃一大截了。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-5136226727027761045?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/5136226727027761045/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/02/av.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5136226727027761045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5136226727027761045'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/02/av.html' title='Audio/Video'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-1992932285433959354</id><published>2011-01-29T19:20:00.007+08:00</published><updated>2011-05-26T15:08:59.961+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Western film</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    西部片必看，喜欢美国那段历史背景，情节也好看。&lt;br /&gt;    &lt;br /&gt;    有个好处就是无论什么时候拍摄的，它描述的都是100多年前的历史，因此始终是那些场面: 荒山野岭，&lt;br /&gt;破烂小镇，主角戴个牛仔帽，骑着马尘土飞扬，感觉就到了中国的农村。因此曾经有人到跟前说: 这个片你&lt;br /&gt;看过了吧？他还以为是同一个片呢：）&lt;br /&gt;&lt;br /&gt;    故事中基本都是些粗人，没啥文化。一般就主角帅气，其它人长的一个比一个萎琐，一身破破烂烂的衣&lt;br /&gt;服，还有穿着更原始的土匪和 Indian tribe。对演员的要求就是骑术要好，不用宏伟的场面，演员也无需&lt;br /&gt;化妆，最好早上起来胡子也别刮，脸也别洗，衣服也不用换新的，越破越好：）&lt;br /&gt;&lt;br /&gt;    西部片里充满正义和邪恶，因此能了解美国司法系统的运作，以及美国近代历史的发展历程。通过人物&lt;br /&gt;之间的冲突还能看出美国人民族性格中可取的一面: perseverance，determination，courage。。。&lt;br /&gt;&lt;br /&gt;    即使是美国40年代的片子，也比国内现在拍的好看。国内就一部《双旗镇刀客》好看，属于西部片风格。&lt;br /&gt;这个和民族性格有关，中国人，越南人，印度人，以及东南亚一带的人，民族性格都比较懦弱，确实不适合&lt;br /&gt;拍西部片。日本人的民族性格适合拍西部片，但场面不够狂野，情节也罗嗦，不好看。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;     首先要了解一些基本的度量单位，做到心中有数。比如一个人出去卖牛说要走 300miles，那心里得清&lt;br /&gt;楚是要走大约 900里地，确实很远；如果一个农民有 10acre 土地，那大约就是60亩地，国内农村都说“30亩&lt;br /&gt;地一头牛，老婆孩子热炕头”，可见这个农民拥有的土地还是挺多的。&lt;br /&gt;    &lt;br /&gt;    在国内，1亩地是666平米; 农村说的一垧地就是一公顷，大约是15亩，10000平米。 &lt;br /&gt;&lt;br /&gt;    了解度量是很重要的。记得高中一个暑假候，我替大姐去上班，铺路，哪里有坑就扬上沙子把坑填上。&lt;br /&gt;走过来一个老大爷，问离石咀还有多远？道路两旁有石头碑，上面写着0，1，2。。。我知道石咀那边的碑上&lt;br /&gt;写的是15。而我干活的地方在3左右，因此对老大爷说：差不多还有12里地。老大爷答应一声继续向前走了。&lt;br /&gt;我垫完了跟前的土坑，就继续骑自行车往前走，中途超过了这个老大爷，在一处坑多的地方停下来了。过了&lt;br /&gt;一会儿老大爷又走到我跟前了，老大爷说：孩子，我问了下别人，他们怎么都说还有20多里地呢？我当时一愣，&lt;br /&gt;心想石咀就是15啊，就说大爷你还是坐车吧，挺远的。等我垫完坑了一想，明白了：那个石碑上写的是公里&lt;br /&gt;数，不是日常老百姓说的里。大爷，不是我故意骗你，也不是我没文化，只是你遇到了一个书呆子。&lt;br /&gt;&lt;br /&gt;    西部片里常用的度量，大概估算就行:&lt;br /&gt;&lt;br /&gt;  dozen   12个&lt;br /&gt;  pound   1斤&lt;br /&gt;  yard    1米&lt;br /&gt;&lt;br /&gt;  acre    6亩地，4000平米&lt;br /&gt;&lt;br /&gt;  inch    2.5厘米&lt;br /&gt;  mile    3里地&lt;br /&gt;  feet    1/3 米&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    在西部片里，$ 是很大的单位，19世纪美国还没有统一的纸币，各地纸币购买力不同，因此gold作为流&lt;br /&gt;通货币最受欢迎。农场主大老远的把牛赶去卖给牛贩子每头牛才10几$，国内现在一头牛8000元左右，因此西&lt;br /&gt;部片里 1$ 大概相当于当前国内400元。可以用民国初年的袁大头银元来类比，说是一块钱，实际很值钱，能&lt;br /&gt;买很多东西，比如今纸币的一块钱值钱很多倍。日常说的都是些小单位，比如一杯 whisky 只卖几个cents。&lt;br /&gt;又比如一个同伙死了，有个牛仔就唠叨说死者生前欠他 6 bits，在计算机里，bit 是最小的单位，如果把&lt;br /&gt;bit也想象成很小的钱的单位，那就会觉得这个牛仔很小气。实际却不是这样，6 bits 接近 1$ 了，相当于&lt;br /&gt;国内300元，对一个没工作的粗人来说，不是小数目了。当然对方刚死就说欠自己钱，这个牛仔确实不义气，&lt;br /&gt;后来这个gang果然内讧了，但这个牛仔起初站到了坏的一边，后来又跑好的这边来了。这里的 6bits 一句&lt;br /&gt;唠叨就是一个伏笔，说明这个牛仔不算好也不算坏。&lt;br /&gt;&lt;br /&gt;                bit     1/8 $&lt;br /&gt;                dime    1/10 $&lt;br /&gt;                cent    1/100 $&lt;br /&gt;                nickel  5 cents&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;    西部片里的枪就两种: pistol  shotgun。很少涉及到连发的机枪。&lt;br /&gt;前者跨在腰间，这类人叫 gunfighter，是西部片里的主角，拔枪快，枪法准，一枪直接命中对方心脏。&lt;br /&gt;后者外形很像国内以前的洋炮，长管，发射散弹，普通人也很容易用。&lt;br /&gt;gunfighter 拔枪叫 draw，轻易不拔，拔出来就会有人丧命。&lt;br /&gt;&lt;br /&gt;    Texas 养牛的多，场主去北方卖牛要走很远的路，不仅要风餐露宿，路过 Indian 的领地要留过路费，&lt;br /&gt;还要防备土匪。比如土匪把牛群驱散然后抢牛，有的甚至把卖牛的人杀掉；即使成功卖了牛，在回来的路&lt;br /&gt;上，还可能被土匪绑票抢钱。和墨西哥接壤的地方，还会有墨西哥土匪，特征就是戴的帽子像斗笠，一口&lt;br /&gt;西班牙语，常说 Amigo! Adios，Rio Grande。。。&lt;br /&gt;&lt;br /&gt;     Civil War，1861 ~ 1865。北方叫Union，军服颜色为blue，颜色较深；南方叫 Confederacy，Dixie，&lt;br /&gt;被北方称为Rebel，军服颜色为grey，颜色较浅。战争是野蛮的，无所谓好坏，很多时候兵就是匪。一般都&lt;br /&gt;是把 Civil War 当做时代背景，然后重点描述几个主角，有的是为了金子，有的是为了抢军队的军火。&lt;br /&gt;&lt;br /&gt;    Indian 也被称为 Injun，对女的有个蔑称叫 squaw。身上会戴很多小装饰品，首领会戴一顶有很多羽毛&lt;br /&gt;的帽子。常见的几个tribe: Comanche，Apaches，Sioux，Cheyennes，Choctaw。&lt;br /&gt;其中前3个出现的最频繁，好斗。Indian 战斗冲锋时是嘴里会 Ho Ho Ho 的叫，他们会把俘虏的头皮连头发&lt;br /&gt;一起割下来，然后都绑在自己的一个棍子上当做战利品，绑的越多说明越英勇。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    关于白人和 Indian tribe 的争斗，容易被与美国为敌的独裁政客利用，上纲上线说白人屠杀 Indian。&lt;br /&gt;根本不是说的那么简单，实际情况很复杂。要知道凡事都有两方面。提到农民，Indian，一方面他们表现为&lt;br /&gt;淳朴，简单；另一方面也有野蛮和无知。独裁者在处理国内问题时，只提农民野蛮无知的一面；而提敌对国&lt;br /&gt;家的Indian时，只提简单淳朴的一面。文化冲突很复杂，如同宗教之间的争斗一样，很难说清楚谁对谁错。&lt;br /&gt;比如 saloon 里会有很多酒鬼，Indian 喝酒之后容易耍酒疯，拿个枪到处乱射；或者在舞会上，白人是两&lt;br /&gt;个人一小步一小步的跳，而 Indian 那舞蹈很狂野，一个人得占5个人的地方，屁股一扭就把身边的白人撞&lt;br /&gt;一边去了：）如果手里再拿个棍子那估计周围每个白人的脑袋上都得有个大包：）因此有的 saloon 就禁止&lt;br /&gt;Indian 入内喝酒，有的舞会也禁止 Indian 入内，这种事都是有原因的。有人说上世纪30年代的上海有的&lt;br /&gt;公园挂“华人与狗不得入内”的牌子，这也是有原因的，还是国人进去做出让人不能容忍的事情了对方才会这&lt;br /&gt;样。而且近些年历史学者的调查结果说从来就没有过那个牌子，都是苏联那一套用来挑唆民族仇恨的。&lt;br /&gt;&lt;br /&gt;    1492年，Columbus 为证明Earth是球形的，反方向航行意图到达印度，无意种发现了美洲大陆。当时所&lt;br /&gt;有人都认为只有欧洲亚洲和非洲大陆，没想到中间还有个美洲。此后，陆续有欧洲人远渡重洋去美洲，自然&lt;br /&gt;就和美洲的土著Indian发生冲突。白人的优点是有技术，有现代文明的影子，缺点是贪婪，不断扩大地盘，&lt;br /&gt;破坏自然环境。可是 Indian 并不是一个整体，而是多个部落构成的，处于原始社会的状态，有些部落彼此&lt;br /&gt;之间有常年的争斗，白人去了之后，有的部落就依靠白人去攻击另外一个部落。有的部落比如 Comanche，&lt;br /&gt;Apache 非常好斗，如果有白人去他们的领地，有时没怎么交流明白呢就把白人杀了，然后抢走车马物品；&lt;br /&gt;白人经过 Indian 的领地，也时常遭到 Indian 的抢劫。这样的事发生多了，白人就动用军队了。本来就说&lt;br /&gt;不清楚谁对谁错，一旦发生战争了，就更没有对错了，战争一概是最后谁打赢了谁就是对的，哪怕开战之前&lt;br /&gt;你是对的，只要战败了，那你就会被说成是挑起战争的始作俑者。如果白人不去美洲大陆，自然不会有冲突，&lt;br /&gt;可即使白人不去，黄人以后也会去。比如100年前欧洲白人在非洲投资设厂，被当时落后的黄人说成是殖民&lt;br /&gt;者侵略者，二战后白人陆续退出了非洲，但现在中国向好多非洲国家投资建厂，有的破坏环境，和当地人也&lt;br /&gt;发生了激烈的冲突，但中国人确实改善了他们很多人的生活，因此不能单纯说中国人就是侵略者。同样，白&lt;br /&gt;人去美洲也不能偏颇的说是去做坏事，说屠杀那是噱头，因为Indian 也割下了很多白人平民的头皮。白人&lt;br /&gt;也并不是无缘无故就对 Indian 进行战争，而且专门给 Indian 留出了reserve，虽然地盘比原来小多了，&lt;br /&gt;生活却够了，而且由白人负责给Indian提供食品等生活用品，Indian 再也不用为打猎发愁了。胜败双方都&lt;br /&gt;后退一步，自然海阔天空。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    通过西部片，可以粗略了解美国的司法运作。虽然不了解法律细节，但仍可看出当时法律的执行情况总&lt;br /&gt;的说来还是不错的，比100多年后现在的很多发展中国家执行情况都好。直到现在美国所用的宪法还是200多&lt;br /&gt;年前的，只在小地方做了修修补补，能成为一个长时间稳定强大的大国，可见法律被执行的很好。&lt;br /&gt;&lt;br /&gt;    一般一个小镇就两个政府人员维护治安: Marshall，Sheriff。&lt;br /&gt;前者更武力一些，是拿枪和敌人直接冲突的，胸前会戴个星形的金属作为标志；后者偏文一些，负责交涉。&lt;br /&gt;他们两个专门有一间房子，里面有枪，还有个小监狱，当有人犯错了就暂时关在监狱里，稍后在派人把犯人&lt;br /&gt;押送到上级正规的监狱。有时 Marshall 或 Sheriff 会临时找几个deputy 拿枪维护治安，这样的下属叫&lt;br /&gt;posse，posse 在承担责任前要举手宣誓的。&lt;br /&gt;&lt;br /&gt;    和现实一样，在西部片里，这两个人不一定总是正义一方，有时恰恰就是邪恶的一方。&lt;br /&gt;    有的片里只有 Marshall Sheriff 中的一个，无论哪个，反正有一点：胸前戴五角星的人就是负责当&lt;br /&gt;地治安的。&lt;br /&gt;    &lt;br /&gt;    其它法律相关的词汇只能看英文原文了:&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;jury   pl. v.]&lt;br /&gt;    (also panel, jury panel especially in AmE) a group of members of the public who listen to &lt;br /&gt;the facts of a case in a court of law and decide whether or not sb is guilty of a crime:&lt;br /&gt;&lt;br /&gt;    陪审团，一般是12个人。在法庭上听完当事人双方律师的陈述后，对犯人是否有罪作出决定。&lt;br /&gt;&lt;br /&gt;    实在是想多了解一下美国的司法系统，黑帮片里都会涉及到，《Jackie Brown》里面就是个粗略了解司&lt;br /&gt;法程序的好例子。&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;probation  noun [U]&lt;br /&gt;    (law) a system that allows a person who has committed a crime not to go to prison if they&lt;br /&gt;behave well and if they see an official (called a PROBATION OFFICER) regularly for a fixed&lt;br /&gt;period of time:&lt;br /&gt;&lt;br /&gt;    男主角 Ordell 贩卖枪支，手下有个小弟 Beaumont，Beau 蹲了9个月监狱，然后出来正处于4年的&lt;br /&gt;probation 期，Beau能惹事，在这期间携带走私的机枪被警察发现了，预计是将被重新判刑10年。而&lt;br /&gt;Ordell 知道 Beau 为了减刑恐怕会把老板卖枪的事告诉警察，直接把 Beau 做掉了。&lt;br /&gt;&lt;br /&gt;    警方发现 Beau 尸体后，从 Beau 处的遗物中发现了 Ordell 的另一个手下 Jackie。Jackie 利用空姐&lt;br /&gt;的身份为 Ordell 携带卖枪的钱，这天她携带 $50,000 从墨西哥回美国，警察查她包，发现了这笔钱。海关&lt;br /&gt;规定超过 $10,000 就要事先申请，否则就要蹲两年监狱，并且罚款 $250,000，警察又从 Jackie 的包里找&lt;br /&gt;到一小包毒品，警察跟 Jackie 说只要她配合咬出 Ordell，就不把这事告诉海关。Jackie 年薪只有 $16,000，&lt;br /&gt;根本没钱，更不想蹲监狱。Jackie 只好跟他们合作，这样就能按携带毒品罪处理，可能只判1年，甚至还会&lt;br /&gt;获得 probation 的机会。&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;plead&lt;br /&gt;    to state in a court of law that you are guilty or not guilty of a crime:&lt;br /&gt;[V-ADJ] to plead guilty / not guilty * [V] How do you plead? (= said by the judge at the start of&lt;br /&gt; the trial) * The accused was deemed unfit to plead. * [VN] [no passive] He advised his client to&lt;br /&gt;plead insanity (= say that he / she was mentally ill and therefore not responsible for his / her&lt;br /&gt; actions).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;bail   noun, verb &lt;br /&gt;&lt;br /&gt;   [U] money that sb agrees to pay if a person accused of a crime does not appear at their trial.&lt;br /&gt; When bail has been arranged, the accused person is allowed to go free until the trial:&lt;br /&gt;Can anyone put up bail for you? * She was released on ｣2 000 bail. * Bail was set at $1 million. *&lt;br /&gt; He committed another offence while he was out on bail (= after bail had been agreed). * The judge&lt;br /&gt; granted / refused bail. * She jumped / skipped bail (= did not appear at her trial).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Jackie 上了法庭，采用的策略是 stand mute。如果当事人觉得自己没罪，可以 plead not guilty，&lt;br /&gt;有时当事人觉得躲不过去，不想把事闹大，也可以 plead guilty，坦白了能被轻判。Jackie 是保持沉默了，&lt;br /&gt;当然，是警察让她这么做的。然后法官就允许 Jackie 先交 $10,000 bail bond，先把 Jackie 暂时拘留，&lt;br /&gt;收到这笔钱就可以出去恢复自由身，然后等6周后才正式审判。如果6周后开审时 Jackie 没到场，那这&lt;br /&gt;$10,000 就被没收了。本来携带这点儿毒品的 bail bond 只需 $1000，但由于Jackie 有前科，所以法官按&lt;br /&gt;10倍要求了。Jackie 没钱，只好由 Ordell 来处理。&lt;br /&gt;&lt;br /&gt;    Ordell 把 $10,000 给了 Max，由这个 bail bondsman 去把 Jackie 从拘留所给赎出来。。。。。。&lt;br /&gt;&lt;br /&gt;    还有一个常见的 parole，比如 《Shawshank Redemption》里的 Morgan，在监狱里表现好，就给一次&lt;br /&gt;parole 的机会，成功了就可以在外面服刑了。&lt;br /&gt;&lt;br /&gt;--- Oxford Advanced Learner's Dictionary ---&lt;br /&gt;parole   noun&lt;br /&gt;    [U] permission that is given to a prisoner to leave prison before the end of their SENTENCE&lt;br /&gt; on condition that they behave well: to be eligible for parole * She was released on parole.&lt;br /&gt;&lt;br /&gt;    还有两个常用的律师和LA警署，LA 犯罪事件频繁，而且重罪较多，凡是犯罪率高的城市，警察都不干净，&lt;br /&gt;因此 L.A.P.D 也出名了:&lt;br /&gt;&lt;br /&gt;DA        District Attorney   lawyer&lt;br /&gt;L.A.P.D   LA Personal Department&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-1992932285433959354?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/1992932285433959354/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2011/01/western-film.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1992932285433959354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1992932285433959354'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2011/01/western-film.html' title='Western film'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-3986083122553316572</id><published>2010-11-11T15:33:00.010+08:00</published><updated>2011-07-05T11:52:08.366+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 grams'/><title type='text'>Kennedy Berlin Wall Speech</title><content type='html'>&lt;pre&gt;&lt;br /&gt;                                       &lt;br /&gt;                                   John F. Kennedy  &lt;br /&gt;                                        &lt;br /&gt;                                    June 26, 1963&lt;br /&gt;&lt;br /&gt;    I am proud to come to this city as the guest of your distinguished Mayor, who has symbolized&lt;br /&gt;throughout the world the fighting spirit of West Berlin. And I am proud to visit the Federal&lt;br /&gt;Republic with your distinguished Chancellor who for so many years has committed Germany to&lt;br /&gt;democracy and freedom and progress, and to come here in the company of my fellow American, &lt;br /&gt;General Clay, who has been in this city during its great moments of crisis and will come again&lt;br /&gt;if ever needed.&lt;br /&gt;&lt;br /&gt;    Two thousand years ago the proudest boast was "civis Romanus sum." Today, in the world of&lt;br /&gt;freedom, the proudest boast is "Ich bin ein Berliner."&lt;br /&gt;&lt;br /&gt;    I appreciate my interpreter translating my German!&lt;br /&gt;&lt;br /&gt;    There are many people in the world who really don't understand, or say they don't, what is&lt;br /&gt;the great issue between the free world and the Communist world. Let them come to Berlin. There&lt;br /&gt;are some who say that communism is the wave of the future. Let them come to Berlin. And there&lt;br /&gt;are some who say in Europe and elsewhere we can work with the Communists. Let them come to Berlin.&lt;br /&gt;And there are even a few who say that it is true that communism is an evil system, but it permits&lt;br /&gt;us to make economic progress. Lass' sie nach Berlin kommen. Let them come to Berlin.&lt;br /&gt;&lt;br /&gt;    Freedom has many difficulties and democracy is not perfect, but we have never had to put a&lt;br /&gt;wall up to keep our people in, to prevent them from leaving us. I want to say, on behalf of my&lt;br /&gt;countrymen, who live many miles away on the other side of the Atlantic, who are far distant from&lt;br /&gt;you, that they take the greatest pride that they have been able to share with you, even from a&lt;br /&gt;distance, the story of the last 18 years. I know of no town, no city, that has been besieged for&lt;br /&gt;18 years that still lives with the vitality and the force, and the hope and the determination of&lt;br /&gt;the city of West Berlin. While the wall is the most obvious and vivid demonstration of the&lt;br /&gt;failures of the Communist system, for all the world to see, we take no satisfaction in it, for&lt;br /&gt;it is, as your Mayor has said, an offense not only against history but an offense against&lt;br /&gt;humanity, separating families, dividing husbands and wives and brothers and sisters, and&lt;br /&gt;dividing a people who wish to be joined together.&lt;br /&gt;&lt;br /&gt;    What is true of this city is true of Germany--real, lasting peace in Europe can never be&lt;br /&gt;assured as long as one German out of four is denied the elementary right of free men, and that&lt;br /&gt;is to make a free choice. In 18 years of peace and good faith, this generation of Germans has&lt;br /&gt;earned the right to be free, including the right to unite their families and their nation in&lt;br /&gt;lasting peace, with good will to all people. You live in a defended island of freedom, but your&lt;br /&gt;life is part of the main. So let me ask you as I close, to lift your eyes beyond the dangers of&lt;br /&gt;today, to the hopes of tomorrow, beyond the freedom merely of this city of Berlin, or your&lt;br /&gt;country of Germany, to the advance of freedom everywhere, beyond the wall to the day of peace&lt;br /&gt;with justice, beyond yourselves and ourselves to all mankind.&lt;br /&gt;&lt;br /&gt;    Freedom is indivisible, and when one man is enslaved, all are not free. When all are free,&lt;br /&gt;then we can look forward to that day when this city will be joined as one and this country and&lt;br /&gt;this great Continent of Europe in a peaceful and hopeful globe. When that day finally comes, as&lt;br /&gt;it will, the people of West Berlin can take sober satisfaction in the fact that they were in&lt;br /&gt;the front lines for almost two decades.&lt;br /&gt;&lt;br /&gt;    All free men, wherever they may live, are citizens of Berlin, and, therefore, as a free man,&lt;br /&gt;I take pride in the words "Ich bin ein Berliner."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;评论:&lt;br /&gt;&lt;br /&gt;    美国总统的对外演讲都通俗易懂，没有晦涩的词汇，具有启明灯般的魅力。&lt;br /&gt;&lt;br /&gt;    1945年二战结束后，德国被整体分为西德和东德，西德归美英法控制，东侧归苏联控制，&lt;br /&gt;将当时的德国分裂为两个国家：&lt;br /&gt;&lt;br /&gt;                西德  Federal Republic of Germany   联邦德国&lt;br /&gt;                东德  German Democratic Republic    民主德国&lt;br /&gt;&lt;br /&gt;    其中柏林整体位于苏联控制范围内，鉴于柏林的重要性，美英法要求将柏林也一分为二，同样是西侧归&lt;br /&gt;美英法控制，称为西柏林；东侧归苏联控制，叫东柏林。这样西柏林就成了红色海洋中的一个异类小岛，偏&lt;br /&gt;偏就是这个小岛吸引了无数的东柏林市民。&lt;br /&gt;&lt;br /&gt;    单看国名，大家基本都会认为民主德国更好，会选择去民主德国。不幸的是，魔鬼都会掩盖自己的丑陋&lt;br /&gt;而采用花哨光鲜的外表。从1945年之后的10多年里，大批的东德市民无法忍受贫困高压的生活而逃向西德，&lt;br /&gt;于是近代一直被西中欧国家视为贪得无厌的大章鱼的俄罗斯，想出了一个鬼点子: 造一面墙。 &lt;br /&gt;&lt;br /&gt;　　1961年8月13日，绕着整个西柏林建了一圈的铁丝网，其中东西德交界的地方建的则是防范更加严密的 &lt;br /&gt;砖墙，有持枪的警卫守护。表面是为了围住西柏林，而东德市民很清楚：是他们自己被关在了监狱中。很多&lt;br /&gt;家庭因此被分隔两地，柏林墙也随之成为东西冷战的最显著的标志。肯尼迪总统在1963年到西柏林发表了上&lt;br /&gt;述演说，明确说了民主不是完美的，自由国度也会有很多困难，但是自由国度绝不会建一面墙来限制自己的&lt;br /&gt;国民。这面墙虽然挡住了大多数的东德市民，却让全世界的人都看清了孰优孰劣。因此肯尼迪说，如果谁还&lt;br /&gt;糊里糊涂，到柏林墙这里看看就啥都明白了。由于西柏林成了自由国度瓦解独裁专制的最前线，因此总统又&lt;br /&gt;说如果将来德国统一了，欧洲大陆也大同了，那柏林人的贡献是巨大的，做为一个柏林人将是很自豪的：&lt;br /&gt;Ich bin ein Berlner （我是一个柏林人）。后来德国人将肯尼迪演讲的这个广场就改名为肯尼迪广场。&lt;br /&gt;&lt;br /&gt;    接下来的28年，大批东德人为了投奔自由而翻墙成功，很多人为此而丧命。苏联一方先后提升了几次防&lt;br /&gt;卫强度，投入了大量的资金，仍然有人用各种奇异的手段翻墙成功: 藏车里、挖地道、渡河、驾驶飞机穿越、&lt;br /&gt;伪造通关文件......到了1980年代后期，东德有9万秘密警察，近20万告密者，东德 1/3 的人口都处于秘密&lt;br /&gt;警察的监视之下。到了1988年，美国 Reagan 总统又到了柏林墙下，公开呼吁:&lt;br /&gt;         &lt;br /&gt;         Mr Gorbachev，Open this gate!&lt;br /&gt;         Mr Gorbachev，Tear down this wall! &lt;br /&gt;&lt;br /&gt;    进入1989年，独裁者想进一步升级Wall的防卫强度，好在还没有实施，1989年11月9日，阻挡时间长达&lt;br /&gt;28年之久的柏林墙被推倒，东德人民重获自由。&lt;br /&gt;&lt;br /&gt;    第二年，两德统一。为世界和平做出重大贡献的 Gorbachev 获得 Nobel Peace Prize。&lt;br /&gt;&lt;br /&gt;    20年后的2009年年底，当年柏林墙倒掉的当事人 Gorbachev，Bush, Kohl  来到柏林墙参加纪念仪式。&lt;br /&gt;欧盟成员国不断扩大，欧元成功运作，基本实现了欧洲的大同。&lt;br /&gt; &lt;br /&gt;    短短20年，当年受贫穷困扰的红色区域德国，匈牙利，捷克，斯洛伐克，斯洛文尼亚 都成了发达国家；&lt;br /&gt;波兰，罗马尼亚，保加利亚人均收入也都已超过1万美元。&lt;br /&gt;&lt;br /&gt;    东亚这边，一直受美国控制的日本早就成了发达国家；而韩国即使在北朝鲜的干扰下，中间经历过军政&lt;br /&gt;府的独裁，仍旧摆脱了20年前亚洲四小龙的束缚，昂首成为了发达国家；同为中国人的台湾和香港也都已经&lt;br /&gt;步入了发达地区的行列；南边的印度是目前最大的民主政权，发展势头强劲，有些中国人习惯性的想进去靠&lt;br /&gt;行贿手段取得特权然后投资，发现权利分散，行不通；越南连总书记都开始差额选举，变天指日可待。&lt;br /&gt;   &lt;br /&gt;    Wall 没能阻止世界大势的走向，肯尼迪总统当年所期望的梦想都陆续实现了。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-3986083122553316572?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/3986083122553316572/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/11/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/3986083122553316572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/3986083122553316572'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/11/blog-post.html' title='Kennedy Berlin Wall Speech'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-212839251170435178</id><published>2010-11-04T16:39:00.002+08:00</published><updated>2010-11-18T14:00:47.571+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 grams'/><title type='text'>public</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    同一个 Canada 的朋友聊起地沟油，三聚氰胺等食品安全问题，我说还是国外的食品卫生让人放心，朋&lt;br /&gt;友说如果这边要有这种事，那这人就彻底完了，这属于危害公共安全！我就想到了电影《Public Enemies》，&lt;br /&gt;是专门讲美国30年代的大盗 Dillinger 的，这哥们的组织专门抢大银行，而且跨州活动，影响巨大，FBI 费&lt;br /&gt;尽心思才设套将其击毙；还有一部电影《Public Enemy Number One》是介绍法国大盗 Mesrine 的，他从监&lt;br /&gt;狱逃出来之后，为了营救其它人，修养一些日子后，竟然又全副武装开车杀回监狱去了！&lt;br /&gt;&lt;br /&gt;    看来国外形容这种亡命徒都用 Public Enemy ，公共之敌，强调普通民众。但平时听到的却是罪大恶极，&lt;br /&gt;罪犯，暴徒。。。这类词汇，并没有普通民众的影子。而且常听到的关于 "公共" 的词汇就是公安，当然并&lt;br /&gt;没有想到 "公共安全"，我第一印象是想到了警察。&lt;br /&gt;&lt;br /&gt;    而 public 让我想到的是词根 pub，是小酒馆的意思，在美国英语中就叫 saloon。看美国的西部片，&lt;br /&gt;19世纪的美国西部，每个小镇都会有一个 saloon，里面充满酒鬼流氓赌徒，也有很多普通人。saloon 就是&lt;br /&gt;大家聚会娱乐的地方，也是选举 marshall, sheriff 的地方，最公开最热闹。当时美国的选举，最初的一步&lt;br /&gt;就是在 saloon 进行讨论的，选举的时候大家会争论的面红耳赤。100多年后传到了20世纪80年代的中国，&lt;br /&gt;当时国人翻译成 "沙龙"，也是志同道合的人集会的地方。比如音乐界有了沙龙就诞生了《我热恋的故乡》&lt;br /&gt;这种脍炙人口的作品。&lt;br /&gt;&lt;br /&gt;    由 pub 就很容易理解 public 的意思了，进而又衍生出另外一个词汇: Republic。肯定也是和普通大众&lt;br /&gt;相关，常常被宣传成 "共和"，但我实在没想出来到底跟 "和" 有啥关系，只好来看原始解释:&lt;br /&gt;&lt;br /&gt;------ Oxford Advanced Learner's Dictionary ------&lt;br /&gt;republic   noun&lt;br /&gt;a country that is governed by a president and politicians elected by the people and where there&lt;br /&gt;is no king or queen:&lt;br /&gt;newly independent republics * the Republic of Ireland&lt;br /&gt;compare MONARCHY&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;----- Merrian Webster 10th dictionary -----&lt;br /&gt;republic    noun&lt;br /&gt;a government in which supreme power resides in a body of citizens entitled to vote and is exercised&lt;br /&gt;by elected officers and representatives responsible to them and governing according to law&lt;br /&gt;&lt;br /&gt;    自己的想法是对的，根本就没有突出 "和" 的意思，任何一个国家都是 "和" 起来的，根本不用强调。&lt;br /&gt;而是指一个没有皇帝的国家，而且重点突出普通民众和依法行事。这里也看到了例子 Republic of Ireland，&lt;br /&gt;进而想到了 Republic of Korea，Republic of China。总能听到有人称呼韩国为 "大韩民国"，看来这个&lt;br /&gt;Republic 在有些国家被翻译成了 "民国"，这个翻译确实表达出来了普通民众。而后面那个就是中山先生创&lt;br /&gt;建的 "中华民国"。这下终于理解了 Republic 的含义了。&lt;br /&gt;&lt;br /&gt;    进而想到北朝鲜叫什么呢？ Democratic People's Republic of Korea&lt;br /&gt;看着好有魅力啊，在 Republic of Korea 前面加了2个前缀： Democratic People&lt;br /&gt;这要是让一个识字却没文化的人选择，相信99%都会去这个国家。在人民的国家之上又加上 "人民"，还有个&lt;br /&gt;时髦的民主，傻子都会向往。已经有了人民的含义，又加上一个人民，有重复感觉，那就把原来那个换个意&lt;br /&gt;思吧："共和"。&lt;br /&gt;                         &lt;br /&gt;    看来有文化还是很重要的，会思考了就能把魔鬼区分出来，现实中体现出能把人品差的人区别出来。&lt;br /&gt;&lt;br /&gt;     会一门外语是必要的，天天看汉字的明白不到哪里去。技术类，数学系和计算机系的汉语书基本都是垃&lt;br /&gt;圾，成天捧着中文书看的都是技工，水平高不了；人文类更是，很多汉字组合起来就等于lie，比如5000年文&lt;br /&gt;明，四大发明这类忽悠人的说法。年代是很久远，但只有3000年的文明，另外有1000年未定，有1000年是文&lt;br /&gt;化，不是文明。四样发现过，但没有变成文明，而且也不能保证当时别人就没发现，是西方人最终把发现变&lt;br /&gt;成了文明。&lt;br /&gt;&lt;br /&gt;    已经不信任汉语了，看法国，奥地利等非英语类的电影都用英文，看到近代的词汇也查英文，没办法，&lt;br /&gt;是对真理的追求驱动的。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-212839251170435178?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/212839251170435178/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/11/public.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/212839251170435178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/212839251170435178'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/11/public.html' title='public'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-1777151676698178704</id><published>2010-07-09T13:22:00.001+08:00</published><updated>2010-07-09T13:22:43.001+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>MemZone 的阈值</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    proc 是个基于内存的文件系统，全在内存中。&lt;br /&gt;    有时为了优化系统，需要自己修改编译kernel源码。proc 就把常用的kernel参数提供给了用户，这样&lt;br /&gt;通过修改相应参数就可以使系统运行的更好，不必改源码了，连重启都不用，非常方便。&lt;br /&gt;&lt;br /&gt;    比如对于 OOM_Killer，当系统内存低于一定的阈值时，kernel 就会杀掉一个进程释放相应内存以防止&lt;br /&gt;系统crash，想改变这个阈值只需直接修改proc中的参数。如果想自己定一套标准选择杀哪个进程，那就只有&lt;br /&gt;改源码了。&lt;br /&gt;&lt;br /&gt;    网上一个人说当他的 Centos 5.4 还剩600多MB内存时，通过用户进程申请了200MB内存后，kernel就kill&lt;br /&gt;掉系统的某个进程，/var/log/messages 有 OOM_Killer 的记录，但log里看不出什么原因。从没遇到过&lt;br /&gt;OOM_Killer的情况，正好走一遍。他机器的主要参数:&lt;br /&gt;&lt;br /&gt;# uname -a&lt;br /&gt;Linux lisa1043.lisa.com 2.6.18.8-xen #1 SMP Fri Jul 2 17:26:35 CST 2010 i686 i686 i386 GNU/Linux&lt;br /&gt;   &lt;br /&gt;   是个 32 位系统。&lt;br /&gt;&lt;br /&gt;# free -m&lt;br /&gt;             total       used       free     shared    buffers     cached&lt;br /&gt;Mem:          4021       3394        626          0         11         15&lt;br /&gt;-/+ buffers/cache:       3367        653&lt;br /&gt;Swap:            0          0          0&lt;br /&gt;&lt;br /&gt;    可见4GB的内存，page cache 只有26MB了，确实是系统内存紧张了，连 page cache 都快释放没了。&lt;br /&gt;还剩653MB内存free。既然发生了 OOM_Kill，就涉及阈值了。当这个阈值很小时， OOM_Killer 就基本没用，&lt;br /&gt;因为要杀别的进程时，killer进程本身就需要有额外的内存来运行，所以此时基本还是会crash。而如果把&lt;br /&gt;阈值设置太大，就会造成内存的浪费。因此阈值的选择有个tradeoff: 要提高稳定性就不能怕浪费内存。&lt;br /&gt;如何让浪费的内存尽量少就要管理员反复实验再确定了。&lt;br /&gt;&lt;br /&gt;# cat /var/log/messages&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687231] oom-killer: gfp_mask=0x201d2, order=0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687237]  [&lt;c0142b54&gt;] out_of_memory+0x25/0x13d&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687244]  [&lt;c01440b8&gt;] __alloc_pages+0x1fe/0x27e&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687249]  [&lt;c01453fe&gt;] __do_page_cache_readahead+0xef/0x22f&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687253]  [&lt;c013fc15&gt;] sync_page+0x0/0x3b&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687256]  [&lt;c013e939&gt;] __delayacct_blkio_end+0x32/0x35&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687259]  [&lt;c028bf2d&gt;] __wait_on_bit_lock+0x4b/0x52&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687264]  [&lt;f711d985&gt;] dm_any_congested+0x2f/0x35 [dm_mod]&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687273]  [&lt;c014224b&gt;] filemap_nopage+0x151/0x312&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687278]  [&lt;c014c885&gt;] __handle_mm_fault+0x71f/0x1481&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687290]  [&lt;c01f5bd6&gt;] pty_write+0x2a/0x34&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687296]  [&lt;c01efddc&gt;] tty_default_put_char+0x17/0x1a&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687299]  [&lt;c012c3b4&gt;] remove_wait_queue+0xc/0x34&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687302]  [&lt;c01155b5&gt;] __wake_up+0x2a/0x3d&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687308]  [&lt;c028b565&gt;] schedule+0x6a9/0x788&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687313]  [&lt;c0111934&gt;] do_page_fault+0x611/0xa5c&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687319]  [&lt;c0111323&gt;] do_page_fault+0x0/0xa5c&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687322]  [&lt;c0104ed7&gt;] error_code+0x2b/0x30&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687329] Mem-info:                       &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687330] DMA per-cpu:                    &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687331] cpu 0 hot: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687332] cpu 0 cold: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687334] cpu 1 hot: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687335] cpu 1 cold: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687336] cpu 2 hot: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687337] cpu 2 cold: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687339] cpu 3 hot: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687340] cpu 3 cold: high 0, batch 1 used:0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687341] DMA32 per-cpu: empty            &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687342] Normal per-cpu:                 &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687343] cpu 0 hot: high 186, batch 31 used:19&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687345] cpu 0 cold: high 62, batch 15 used:50&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687346] cpu 1 hot: high 186, batch 31 used:183&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687347] cpu 1 cold: high 62, batch 15 used:56&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687349] cpu 2 hot: high 186, batch 31 used:128&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687350] cpu 2 cold: high 62, batch 15 used:48&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687351] cpu 3 hot: high 186, batch 31 used:30&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687353] cpu 3 cold: high 62, batch 15 used:52&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687354] HighMem per-cpu:                &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687355] cpu 0 hot: high 186, batch 31 used:31&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687356] cpu 0 cold: high 62, batch 15 used:23&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687358] cpu 1 hot: high 186, batch 31 used:31&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687359] cpu 1 cold: high 62, batch 15 used:52&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687360] cpu 2 hot: high 186, batch 31 used:29&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687361] cpu 2 cold: high 62, batch 15 used:46&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687363] cpu 3 hot: high 186, batch 31 used:30&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687364] cpu 3 cold: high 62, batch 15 used:31&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687366] Free pages:      565692kB   (780kB HighMem)&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687368] Active:806839 inactive:429      &lt;br /&gt;dirty:0 writeback:0 unstable:0 free:141423 slab:3667 mapped:400 pagetables:1866 &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687371] DMA free:12640kB min:68kB  low:84kB&lt;br /&gt;high:100kB active:0kB inactive:0kB present:16384kB pages_scanned:0 all_unreclaimable? yes&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687372] lowmem_reserve[]: 0 0 851 24149 &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687375] DMA32 free:0kB min:0kB low:0kB  &lt;br /&gt;high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687377] lowmem_reserve[]: 0 0 851 24149 &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687380] Normal free:552272kB min:3696kB low:4620kB&lt;br /&gt;high:5544kB active:0kB inactive:128kB present:872440kB pages_scanned:192 all_unreclaimable? no&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687382] lowmem_reserve[]: 0 0 0 186383  &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687385] HighMem free:780kB min:512kB&lt;br /&gt;low:25796kB high:51080kB active:3227372kB inactive:1588kB present:23857080kB&lt;br /&gt;pages_scanned:6578854 all_unreclaimable? yes                                    &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687387] lowmem_reserve[]: 0 0 0 0       &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687389] DMA: 2*4kB 3*8kB 4*16kB 2*32kB  &lt;br /&gt;1*64kB 3*128kB 1*256kB 1*512kB 1*1024kB 1*2048kB 2*4096kB = 12640kB             &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687394] DMA32: empty                    &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687395] Normal: 948*4kB 1066*8kB        &lt;br /&gt;621*16kB 281*32kB 99*64kB 29*128kB 10*256kB 1*512kB 0*1024kB 0*2048kB 124*4096kB = 552272kB&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687400] HighMem: 71*4kB 4*8kB 5*16kB    &lt;br /&gt;0*32kB 0*64kB 1*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 780kB        &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687405] Swap cache: add 0, delete 0, find 0/0, race 0+0&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687406] Free swap  = 0kB                &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687407] Total swap = 0kB                &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687408] Free swap:            0kB       &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740869] 6186476 pages of RAM            &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740872] 6186476 pages of RAM            &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740874] 5964270 pages of HIGHMEM        &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740876] 72276 reserved pages            &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740877] 5441 pages shared               &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740879] 0 pages swap cached             &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740880] 0 pages dirty                   &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740881] 0 pages writeback               &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740883] 400 pages mapped                &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740884] 3667 pages slab                 &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740885] 1866 pages pagetables           &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740887] 5964270 pages of HIGHMEM        &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740888] 72276 reserved pages            &lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.740889] 5440 pages shared               &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740890] 0 pages swap cached             &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740891] 0 pages dirty                   &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740891] 0 pages writeback               &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740892] 400 pages mapped                &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740893] 3667 pages slab                 &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740894] 1866 pages pagetables           &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740978] Out of Memory: Kill process 23774 (bash)&lt;br /&gt;score 22314 and children.                                          &lt;br /&gt;Jun 10 10:01:19 lisa1043 kernel: [23217.740980] Out of memory: Killed process 23970 (runmem).&lt;br /&gt;                             ....&lt;br /&gt;     &lt;br /&gt;   虽然看不懂log的意思，但是有很多keyword可供参考: &lt;br /&gt;            DMA DMA32 Normal HighMem lowmem_reserve[] active inactive&lt;br /&gt;这都是 zone 里的词汇，联想到 lru list。&lt;br /&gt;&lt;br /&gt;# cat /proc/zoneinfo&lt;br /&gt;Node 0, zone      DMA&lt;br /&gt;  pages free     3160&lt;br /&gt;        min      17&lt;br /&gt;        low      21&lt;br /&gt;        high     25&lt;br /&gt;        active   0&lt;br /&gt;        inactive 0&lt;br /&gt;        scanned  0 (a: 17 i: 17)&lt;br /&gt;        spanned  4096&lt;br /&gt;        present  4096&lt;br /&gt;    nr_anon_pages 0&lt;br /&gt;    nr_mapped    1&lt;br /&gt;    nr_file_pages 0&lt;br /&gt;    nr_slab      0&lt;br /&gt;    nr_page_table_pages 0&lt;br /&gt;    nr_dirty     0&lt;br /&gt;    nr_writeback 0&lt;br /&gt;    nr_unstable  0&lt;br /&gt;    nr_bounce    0&lt;br /&gt;        protection: (0, 0, 851, 24149)&lt;br /&gt;  pagesets&lt;br /&gt; all_unreclaimable: 1&lt;br /&gt;  prev_priority:     12&lt;br /&gt;  start_pfn:         0&lt;br /&gt;Node 0, zone   Normal&lt;br /&gt;  pages free     137757&lt;br /&gt;        min      924&lt;br /&gt;        low      1155&lt;br /&gt;        high     1386&lt;br /&gt;        active   48&lt;br /&gt;        inactive 35&lt;br /&gt;        scanned  97 (a: 5 i: 7)&lt;br /&gt;        spanned  218110&lt;br /&gt;        present  218110&lt;br /&gt;    nr_anon_pages 0&lt;br /&gt;    nr_mapped    1&lt;br /&gt;    nr_file_pages 80&lt;br /&gt;    nr_slab      4052&lt;br /&gt;    nr_page_table_pages 1827&lt;br /&gt;    nr_dirty     0&lt;br /&gt;    nr_writeback 0&lt;br /&gt;    nr_unstable  0&lt;br /&gt;    nr_bounce    0&lt;br /&gt;       protection: (0, 0, 0, 186383)&lt;br /&gt;  pagesets&lt;br /&gt;    cpu: 0 pcp: 0&lt;br /&gt;              count: 9&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 0 pcp: 1&lt;br /&gt;              count: 61&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 24&lt;br /&gt;    cpu: 1 pcp: 0&lt;br /&gt;              count: 46&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 1 pcp: 1&lt;br /&gt;              count: 59&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 24&lt;br /&gt;    cpu: 2 pcp: 0&lt;br /&gt;              count: 60&lt;br /&gt;             high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 2 pcp: 1&lt;br /&gt;              count: 51&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 24&lt;br /&gt;    cpu: 3 pcp: 0&lt;br /&gt;              count: 121&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 3 pcp: 1&lt;br /&gt;              count: 53&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 24&lt;br /&gt;  all_unreclaimable: 0&lt;br /&gt;  prev_priority:     2&lt;br /&gt;  start_pfn:         4096&lt;br /&gt;Node 0, zone  HighMem&lt;br /&gt;  pages free     11114&lt;br /&gt;        min      128&lt;br /&gt;        low      6449&lt;br /&gt;        high     12770&lt;br /&gt;        active   795251&lt;br /&gt;        inactive 381&lt;br /&gt;        scanned  297953 (a: 0 i: 20)&lt;br /&gt;        spanned  5964270&lt;br /&gt;        present  5964270&lt;br /&gt;    nr_anon_pages 793116&lt;br /&gt;    nr_mapped    2155&lt;br /&gt;    nr_file_pages 2494&lt;br /&gt;    nr_slab      0&lt;br /&gt;    nr_page_table_pages 0&lt;br /&gt;    nr_dirty     38&lt;br /&gt;    nr_writeback 0&lt;br /&gt;    nr_unstable  0&lt;br /&gt;    nr_bounce    0&lt;br /&gt;        protection: (0, 0, 0, 0)&lt;br /&gt;  pagesets&lt;br /&gt;    cpu: 0 pcp: 0&lt;br /&gt;              count: 152&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 0 pcp: 1&lt;br /&gt;              count: 0&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 54&lt;br /&gt;    cpu: 1 pcp: 0&lt;br /&gt;              count: 184&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 1 pcp: 1&lt;br /&gt;              count: 5&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 54&lt;br /&gt;    cpu: 2 pcp: 0&lt;br /&gt;              count: 71&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 2 pcp: 1&lt;br /&gt;              count: 3&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 54&lt;br /&gt;    cpu: 3 pcp: 0&lt;br /&gt;              count: 22&lt;br /&gt;              high:  186&lt;br /&gt;              batch: 31&lt;br /&gt;    cpu: 3 pcp: 1&lt;br /&gt;              count: 5&lt;br /&gt;              high:  62&lt;br /&gt;              batch: 15&lt;br /&gt;  vm stats threshold: 54&lt;br /&gt;  all_unreclaimable: 0&lt;br /&gt;  prev_priority:     2&lt;br /&gt;  start_pfn:         222206&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    以上是系统的三个MemZone: DMA Normal HighMem 的信息，要知道这里面的参数才行。&lt;br /&gt;    每个 Zone 都有各自的free_pages和阈值。当用户进程申请内存时，首先试图在 Zone HighMem 中分配，&lt;br /&gt;如果 free_pages 低于阈值了就转向 Zone Normal 分配，如果 Zone Normal 的 free_pages 也低于阈值就&lt;br /&gt;转向 Zone DMA 分配，如果 Zone DMA 的 free_pages 也低于阈值就只好调 OOM_Killer 杀掉某个进程了。&lt;br /&gt;&lt;br /&gt;    man proc 搜 zoneinfo 没有介绍。到 Documentation/ 下 $ locate proc |grep Docu  找到&lt;br /&gt;filesystems/proc.txt，但里面也没有相关参数介绍，好在指明了详细参数可参考 Documentation/sysctl/&lt;br /&gt;在 Documentation/sysctls/vm.txt 中搜 zoneinfo 终于找到了参数介绍，根据文档来分析:&lt;br /&gt;&lt;br /&gt;    在 zone HighMem 中，11114 &amp;lt; 12770 + protection[3] = 12770 + 0，free pages 低于阈值了，无法&lt;br /&gt;从 Zone HighMem 中分配，进而求助 Zone Normal&lt;br /&gt;    在 zone Normal 中，137757 &amp;lt; 1386 +  protection[3] = 1386 + 186383，free pages 也低于阈值，&lt;br /&gt;也无法分配，转而求助 DMA&lt;br /&gt;    在 zone DMA 中，3160 &amp;lt; 25 + 24149 仍然无法分配&lt;br /&gt;&lt;br /&gt;    此时 OOM_Killer 就会根据一个特定的标准杀掉系统的某个进程。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    文档还说可以通过 /proc/sys/vm/lowmem_reserve_ratio 来调整阈值。如果想增大阈值，就减小&lt;br /&gt;lowmem_reserve_ratio；想减小阈值就增大 lowmem_reserve_ratio。 那人系统的信息是:&lt;br /&gt;&lt;br /&gt;# sysctl -a | grep vm&lt;br /&gt;...&lt;br /&gt;vm.lowmem_reserve_ratio = 256   256     32&lt;br /&gt;vm.panic_on_oom = 0&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;    man proc 搜oom发现 panic_on_oom = 0 表示当系统内存无法满足进程的申请时，将调用 OOM_Killer&lt;br /&gt;杀掉一个进程，而不是直接crash。此时需要减小阈值，也就是增大 lowmem_reserve_ratio，比如 &lt;br /&gt;&lt;br /&gt;# echo  512   512   64 &amp;gt; /proc/sys/vm/lowmem_reserve_ratio&lt;br /&gt;&lt;br /&gt;    具体增大多少可以根据文档中的公式计算。公式如下:&lt;br /&gt;&lt;br /&gt;zone[i]'s protection[j] is calculated by following expression.&lt;br /&gt;&lt;br /&gt;(i &amp;lt; j):&lt;br /&gt;  zone[i]-&amp;gt;protection[j]&lt;br /&gt;  = (total sums of present_pages from zone[i+1] to zone[j] on the node)&lt;br /&gt;    / lowmem_reserve_ratio[i];&lt;br /&gt;(i = j):&lt;br /&gt;   (should not be protected. = 0;&lt;br /&gt;(i &amp;gt; j):&lt;br /&gt;   (not necessary, but looks 0)&lt;br /&gt;&lt;br /&gt;    由上面的公式可以看出，本级阈值的设定会把上一级拉下水。&lt;br /&gt;    本级的阈值计算会用到上一级的 zone 的 present_pages，上一级的 present_pages 越多，本级的&lt;br /&gt;zone 的阈值，即 lowmem_reserve_ratio，就会越大。也就越不容易从低级的 zone 中分配。&lt;br /&gt;    目的很明显: 只要上一级的 zone 中有很多page，就别太过分的在我这分配。比如我是 Normal，&lt;br /&gt;在设定我的阈值时，如果不考虑 HighMem 的 present_pages，此时来了内存分配的请求，如果我和 DMA&lt;br /&gt;都无法满足，由于页面请求是从高级到低级的，不会在返回 HighMem 去尝试，那就会发生 OOM_Killer，&lt;br /&gt;而此时 HighMem 中却可能仍然有很多page可以分配。 &lt;br /&gt;&lt;br /&gt;    protection 这里有点迷糊，本来是3个 zone，怎么 protection 有四个元素呢? 仔细看文档，发现&lt;br /&gt;文档的例子是 x64 机器，而提问题的哥们的机器是i686 32位的。看了源码，64 位多了一个 zone DMA32。&lt;br /&gt;$ vi -t zone  在文件中搜 DMA 找到了 zone_type:&lt;br /&gt;&lt;br /&gt;191 enum zone_type {&lt;br /&gt;192 #ifdef CONFIG_ZONE_DMA&lt;br /&gt;193         /*&lt;br /&gt;194          * ZONE_DMA is used when there are devices that are not able&lt;br /&gt;195          * to do DMA to all of addressable memory (ZONE_NORMAL). Then we&lt;br /&gt;196          * carve out the portion of memory that is needed for these devices.&lt;br /&gt;197          * The range is arch specific.&lt;br /&gt;198          *&lt;br /&gt;199          * Some examples&lt;br /&gt;200          *&lt;br /&gt;201          * Architecture         Limit&lt;br /&gt;202          * ---------------------------&lt;br /&gt;203          * parisc, ia64, sparc  &amp;lt;4G&lt;br /&gt;204          * s390                 &amp;lt;2G&lt;br /&gt;205          * arm                  Various&lt;br /&gt;206          * alpha                Unlimited or 0-16MB.&lt;br /&gt;207          *&lt;br /&gt;208          * i386, x86_64 and multiple other arches&lt;br /&gt;209          *                      &amp;lt;16M.&lt;br /&gt;210          */&lt;br /&gt;211         ZONE_DMA,&lt;br /&gt;212 #endif&lt;br /&gt;213 #ifdef CONFIG_ZONE_DMA32&lt;br /&gt;214         /*&lt;br /&gt;215          * x86_64 needs two ZONE_DMAs because it supports devices that are&lt;br /&gt;216          * only able to do DMA to the lower 16M but also 32 bit devices that&lt;br /&gt;217          * can only do DMA areas below 4G.&lt;br /&gt;218          */&lt;br /&gt;219         ZONE_DMA32,&lt;br /&gt;220 #endif&lt;br /&gt;221         /*&lt;br /&gt;222          * Normal addressable memory is in ZONE_NORMAL. DMA operations can be&lt;br /&gt;223          * performed on pages in ZONE_NORMAL if the DMA devices support&lt;br /&gt;224          * transfers to all addressable memory.&lt;br /&gt;225          */&lt;br /&gt;226         ZONE_NORMAL,&lt;br /&gt;227 #ifdef CONFIG_HIGHMEM&lt;br /&gt;228         /*&lt;br /&gt;229          * A memory area that is only addressable by the kernel through&lt;br /&gt;230          * mapping portions into its own address space. This is for example&lt;br /&gt;231          * used by i386 to allow the kernel to address the memory beyond&lt;br /&gt;232          * 900MB. The kernel will set up special mappings (page&lt;br /&gt;233          * table entries on i386) for each page that the kernel needs to&lt;br /&gt;234          * access.&lt;br /&gt;235          */&lt;br /&gt;236         ZONE_HIGHMEM,&lt;br /&gt;237 #endif&lt;br /&gt;238         ZONE_MOVABLE,&lt;br /&gt;239         __MAX_NR_ZONES&lt;br /&gt;240 };&lt;br /&gt;&lt;br /&gt;/var/log/messages 也说明了 DMA32 为空&lt;br /&gt;Jun 10 10:01:18 lisa1043 kernel: [23217.687341] DMA32 per-cpu: empty&lt;br /&gt;&lt;br /&gt;验证一下:&lt;br /&gt;    Normal 的 protection[3] = zone[2]-&amp;gt;protection[3] =&lt;br /&gt;(zone[3] present_pages) / lowmem_reserve_ratio[2] = 5964270 / 32 = 186383&lt;br /&gt;&lt;br /&gt;    DMA 的 protection[3] = zone[1]-&amp;gt;protection[3] =&lt;br /&gt;(zone[2] present_pages + zone[3] present_pages) / lowmem_reserve_ratio[1] =&lt;br /&gt;(218110 + 5964270 ) / 256 = 24149&lt;br /&gt;&lt;br /&gt;    DMA 的 protection[2] = zone[1]-&amp;gt;protection[2] =&lt;br /&gt;zone[2] present_pages / lowmem_reserve_ratio[1] = 218110 / 256 = 851&lt;br /&gt;&lt;br /&gt;    都符合系统数据，文档说的对，公式这里就不用继续看源码验证了。&lt;br /&gt;    对于这个 lowmem_reserve_ratio 的意义及其存在的目的，文档有介绍，注意文档中的&lt;br /&gt;例子是 x64 架构，有4个 Zone，而 i686 32 位有3个Zone:&lt;br /&gt;&lt;br /&gt;lowmem_reserve_ratio&lt;br /&gt;&lt;br /&gt;For some specialised workloads on highmem machines it is dangerous for&lt;br /&gt;the kernel to allow process memory to be allocated from the "lowmem"&lt;br /&gt;zone.  This is because that memory could then be pinned via the mlock()&lt;br /&gt;system call, or by unavailability of swapspace.&lt;br /&gt;&lt;br /&gt;And on large highmem machines this lack of reclaimable lowmem memory&lt;br /&gt;can be fatal.&lt;br /&gt;&lt;br /&gt;So the Linux page allocator has a mechanism which prevents allocations&lt;br /&gt;which _could_ use highmem from using too much lowmem.  This means that&lt;br /&gt;a certain amount of lowmem is defended from the possibility of being&lt;br /&gt;captured into pinned user memory.&lt;br /&gt;&lt;br /&gt;(The same argument applies to the old 16 megabyte ISA DMA region.  This&lt;br /&gt;mechanism will also defend that region from allocations which could use&lt;br /&gt;highmem or lowmem).&lt;br /&gt;&lt;br /&gt;The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is&lt;br /&gt;in defending these lower zones.&lt;br /&gt;&lt;br /&gt;If you have a machine which uses highmem or ISA DMA and your&lt;br /&gt;applications are using mlock(), or if you are running with no swap then&lt;br /&gt;you probably should change the lowmem_reserve_ratio setting.&lt;br /&gt;&lt;br /&gt;The lowmem_reserve_ratio is an array. You can see them by reading this file.&lt;br /&gt;-&lt;br /&gt;% cat /proc/sys/vm/lowmem_reserve_ratio&lt;br /&gt;256     256     32&lt;br /&gt;-&lt;br /&gt;Note: # of this elements is one fewer than number of zones. Because the highest&lt;br /&gt;      zone's value is not necessary for following calculation.&lt;br /&gt;&lt;br /&gt;But, these values are not used directly. The kernel calculates # of protection&lt;br /&gt;pages for each zones from them. These are shown as array of protection pages&lt;br /&gt;in /proc/zoneinfo like followings. (This is an example of x86-64 box).&lt;br /&gt;Each zone has an array of protection pages like this.&lt;br /&gt;&lt;br /&gt;-&lt;br /&gt;Node 0, zone      DMA&lt;br /&gt;  pages free     1355&lt;br /&gt;        min      3&lt;br /&gt;        low      3&lt;br /&gt;        high     4&lt;br /&gt;        :&lt;br /&gt;        :&lt;br /&gt;    numa_other   0&lt;br /&gt;        protection: (0, 2004, 2004, 2004)&lt;br /&gt;        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;  pagesets&lt;br /&gt;    cpu: 0 pcp: 0&lt;br /&gt;        :&lt;br /&gt;-&lt;br /&gt;These protections are added to score to judge whether this zone should be used&lt;br /&gt;for page allocation or should be reclaimed.&lt;br /&gt;&lt;br /&gt;In this example, if normal pages (index=2) are required to this DMA zone and&lt;br /&gt;watermark[WMARK_HIGH] is used for watermark, the kernel judges this zone should&lt;br /&gt;not be used because pages_free(1355) is smaller than watermark + protection[2]&lt;br /&gt;(4 + 2004 = 2008). If this protection value is 0, this zone would be used for&lt;br /&gt;normal page requirement. If requirement is DMA zone(index=0), protection[0]&lt;br /&gt;(=0) is used.&lt;br /&gt;&lt;br /&gt;    另外，源码也提到了 lowmem_reserve_ratio，$ vi -t zone&lt;br /&gt;&lt;br /&gt;280 struct zone {&lt;br /&gt;281         /* Fields commonly accessed by the page allocator */&lt;br /&gt;282 &lt;br /&gt;283         /* zone watermarks, access with *_wmark_pages(zone) macros */&lt;br /&gt;284         unsigned long watermark[NR_WMARK];&lt;br /&gt;285 &lt;br /&gt;286         /*&lt;br /&gt;287          * We don't know if the memory that we're going to allocate will be freeable&lt;br /&gt;288          * or/and it will be released eventually, so to avoid totally wasting several&lt;br /&gt;289          * GB of ram we must reserve some of the lower zone memory (otherwise we risk&lt;br /&gt;290          * to run OOM on the lower zones despite there's tons of freeable ram&lt;br /&gt;291          * on the higher zones). This array is recalculated at runtime if the&lt;br /&gt;292          * sysctl_lowmem_reserve_ratio sysctl changes.&lt;br /&gt;293          */&lt;br /&gt;294         unsigned long           lowmem_reserve[MAX_NR_ZONES];&lt;br /&gt;295 &lt;br /&gt;296 #ifdef CONFIG_NUMA&lt;br /&gt;297         int node;&lt;br /&gt;298         /*&lt;br /&gt;299          * zone reclaim becomes active if more unmapped pages exist.&lt;br /&gt;300          */&lt;br /&gt;301         unsigned long           min_unmapped_pages;&lt;br /&gt;302         unsigned long           min_slab_pages;&lt;br /&gt;303 #endif&lt;br /&gt;304         struct per_cpu_pageset __percpu *pageset;&lt;br /&gt;305         /*&lt;br /&gt;306          * free areas of different sizes&lt;br /&gt;307          */&lt;br /&gt;308         spinlock_t              lock;&lt;br /&gt;309         int                     all_unreclaimable; /* All pages pinned */&lt;br /&gt;310 #ifdef CONFIG_MEMORY_HOTPLUG&lt;br /&gt;311         /* see spanned/present_pages for more description */&lt;br /&gt;312         seqlock_t               span_seqlock;&lt;br /&gt;313 #endif&lt;br /&gt;314         struct free_area        free_area[MAX_ORDER];&lt;br /&gt;315 &lt;br /&gt;316 #ifndef CONFIG_SPARSEMEM&lt;br /&gt;317         /*&lt;br /&gt;318          * Flags for a pageblock_nr_pages block. See pageblock-flags.h.&lt;br /&gt;319          * In SPARSEMEM, this map is stored in struct mem_section&lt;br /&gt;320          */&lt;br /&gt;321         unsigned long           *pageblock_flags;&lt;br /&gt;322 #endif /* CONFIG_SPARSEMEM */&lt;br /&gt;323 &lt;br /&gt;324 &lt;br /&gt;325         ZONE_PADDING(_pad1_)&lt;br /&gt;326 &lt;br /&gt;327         /* Fields commonly accessed by the page reclaim scanner */&lt;br /&gt;328         spinlock_t              lru_lock;&lt;br /&gt;329         struct zone_lru {&lt;br /&gt;330                 struct list_head list;&lt;br /&gt;331         } lru[NR_LRU_LISTS];&lt;br /&gt;332 &lt;br /&gt;333         struct zone_reclaim_stat reclaim_stat;&lt;br /&gt;334 &lt;br /&gt;335         unsigned long           pages_scanned;     /* since last reclaim */&lt;br /&gt;336         unsigned long           flags;             /* zone flags, see below */&lt;br /&gt;337 &lt;br /&gt;338         /* Zone statistics */&lt;br /&gt;339         atomic_long_t           vm_stat[NR_VM_ZONE_STAT_ITEMS];&lt;br /&gt;340 &lt;br /&gt;341         /*&lt;br /&gt;342          * prev_priority holds the scanning priority for this zone.  It is&lt;br /&gt;343          * defined as the scanning priority at which we achieved our reclaim&lt;br /&gt;344          * target at the previous try_to_free_pages() or balance_pgdat()&lt;br /&gt;345          * invocation.&lt;br /&gt;346          *&lt;br /&gt;347          * We use prev_priority as a measure of how much stress page reclaim is&lt;br /&gt;348          * under - it drives the swappiness decision: whether to unmap mapped&lt;br /&gt;349          * pages.&lt;br /&gt;350          *&lt;br /&gt;351          * Access to both this field is quite racy even on uniprocessor.  But&lt;br /&gt;352          * it is expected to average out OK.&lt;br /&gt;353          */&lt;br /&gt;354         int prev_priority;&lt;br /&gt;355 &lt;br /&gt;356         /*&lt;br /&gt;357          * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on&lt;br /&gt;358          * this zone's LRU.  Maintained by the pageout code.&lt;br /&gt;359          */&lt;br /&gt;360         unsigned int inactive_ratio;&lt;br /&gt;361 &lt;br /&gt;362 &lt;br /&gt;363         ZONE_PADDING(_pad2_)&lt;br /&gt;364         /* Rarely used or read-mostly fields */&lt;br /&gt;365 &lt;br /&gt;366         /*&lt;br /&gt;367          * wait_table           -- the array holding the hash table&lt;br /&gt;368          * wait_table_hash_nr_entries   -- the size of the hash table array&lt;br /&gt;369          * wait_table_bits      -- wait_table_size == (1 &amp;lt;&amp;lt; wait_table_bits)&lt;br /&gt;370          *&lt;br /&gt;371          * The purpose of all these is to keep track of the people&lt;br /&gt;372          * waiting for a page to become available and make them&lt;br /&gt;373          * runnable again when possible. The trouble is that this&lt;br /&gt;374          * consumes a lot of space, especially when so few things&lt;br /&gt;375          * wait on pages at a given time. So instead of using&lt;br /&gt;376          * per-page waitqueues, we use a waitqueue hash table.&lt;br /&gt;377          *&lt;br /&gt;378          * The bucket discipline is to sleep on the same queue when&lt;br /&gt;379          * colliding and wake all in that wait queue when removing.&lt;br /&gt;380          * When something wakes, it must check to be sure its page is&lt;br /&gt;381          * truly available, a la thundering herd. The cost of a&lt;br /&gt;382          * collision is great, but given the expected load of the&lt;br /&gt;383          * table, they should be so rare as to be outweighed by the&lt;br /&gt;384          * benefits from the saved space.&lt;br /&gt;385          *&lt;br /&gt;386          * __wait_on_page_locked() and unlock_page() in mm/filemap.c, are the&lt;br /&gt;387          * primary users of these fields, and in mm/page_alloc.c&lt;br /&gt;388          * free_area_init_core() performs the initialization of them.&lt;br /&gt;389          */&lt;br /&gt;390         wait_queue_head_t       * wait_table;&lt;br /&gt;391         unsigned long           wait_table_hash_nr_entries;&lt;br /&gt;392         unsigned long           wait_table_bits;&lt;br /&gt;393 &lt;br /&gt;394         /*&lt;br /&gt;395          * Discontig memory support fields.&lt;br /&gt;396          */&lt;br /&gt;397         struct pglist_data      *zone_pgdat;&lt;br /&gt;398         /* zone_start_pfn == zone_start_paddr &amp;lt;&amp;lt; PAGE_SHIFT */&lt;br /&gt;399         unsigned long           zone_start_pfn;&lt;br /&gt;400 &lt;br /&gt;401         /*&lt;br /&gt;402          * zone_start_pfn, spanned_pages and present_pages are all&lt;br /&gt;403          * protected by span_seqlock.  It is a seqlock because it has&lt;br /&gt;404          * to be read outside of zone-&amp;gt;lock, and it is done in the main&lt;br /&gt;405          * allocator path.  But, it is written quite infrequently.&lt;br /&gt;406          *&lt;br /&gt;407          * The lock is declared along with zone-&amp;gt;lock because it is&lt;br /&gt;408          * frequently read in proximity to zone-&amp;gt;lock.  It's good to&lt;br /&gt;409          * give them a chance of being in the same cacheline.&lt;br /&gt;410          */&lt;br /&gt;411         unsigned long           spanned_pages;  /* total size, including holes */&lt;br /&gt;412         unsigned long           present_pages;  /* amount of memory (excluding holes) */&lt;br /&gt;413 &lt;br /&gt;414         /*&lt;br /&gt;415          * rarely used fields:&lt;br /&gt;416          */&lt;br /&gt;417         const char              *name;&lt;br /&gt;418 } ____cacheline_internodealigned_in_smp;&lt;br /&gt;     &lt;br /&gt;    其中 free_area[] 就是buddy页面级的分配算法的数据结构。&lt;br /&gt;&lt;br /&gt;那哥们的buddy信息如下:&lt;br /&gt;# cat /proc/buddyinfo&lt;br /&gt;Node 0, zone      DMA      2      3      4      2      1      3      1      1     1      1      2&lt;br /&gt;Node 0, zone   Normal    562    884    360     93     15      7      0      1     1      1    129&lt;br /&gt;Node 0, zone  HighMem    703    380    180    111     34     26      8      3     2      0      2&lt;br /&gt;&lt;br /&gt;第2行 Normal Zone 意义如下: &lt;br /&gt;容量为2^0 个page的链表中有562个chunk可供分配&lt;br /&gt;容量为2^1 个page的链表中有884个chunk可供分配&lt;br /&gt;容量为2^2 个page的链表中有360个chunk可供分配&lt;br /&gt;.....&lt;br /&gt;容量为2^10 个page的链表中有129个chunk可供分配&lt;br /&gt;&lt;br /&gt;    从buddyinfo 可以看出 HighMem 中 2^10 个page的chunk有2个，大小为8MB，无法满足200MB的请求；&lt;br /&gt;Normal 中 2^10 个page的chunk有129个，大小为 129*4MB = 516MB，所以本该能满足内存申请。&lt;br /&gt; &lt;br /&gt;    啥事都有好处和坏处。虽然阈值的设定方法把上级拉下水有很大好处，但在提问哥们那，坏处就显现出来了:&lt;br /&gt;如果上级 present_pages 很少了，由于你把他拉下水了，这时不但没占着便宜，反而被他牵连了，明明自己&lt;br /&gt;有很多页面可供分配，这时却无法分配了。&lt;br /&gt;&lt;br /&gt;    另外，这个buddyinfo 也能看出buddy分配算法的碎片程度。&lt;br /&gt;    &lt;br /&gt;    struct zone 中还有个 lru list 结构就是用来缓存page的，当系统空闲page太少时，kernel就会&lt;br /&gt;回收不再被频繁使用的页面:&lt;br /&gt;&lt;br /&gt; 327         /* Fields commonly accessed by the page reclaim scanner */&lt;br /&gt; 328         spinlock_t              lru_lock;&lt;br /&gt; 329         struct zone_lru {&lt;br /&gt; 330                 struct list_head list;&lt;br /&gt; 331         } lru[NR_LRU_LISTS];&lt;br /&gt;    &lt;br /&gt;    看到这个 lru list，想起来页面分配这里有个问题曾经困惑我好久: &lt;br /&gt;    kernel 启动时就对所有物理页面都做了映射，有pte，highmem 即使没有也能做临时映射；而用户进程&lt;br /&gt;只能在申请页面时才建立pte，从而能够访问物理页面。但既然kernel能访问全部物理页面了，用户进程还咋&lt;br /&gt;申请啊? 反过来，kernel 岂不是也可能破坏用户进程申请的页面吗? 就是觉得 kernel 和用户进程在使用&lt;br /&gt;物理页面时会有冲突。&lt;br /&gt;&lt;br /&gt;    实际上，kernel 做为管理者，确实嫩够访问普通用户进程的页面，但是 kernel 程序员在写代码时会&lt;br /&gt;避免让 kernel 去破坏用户进程的页面。当然对用户进程数据的read操作是有的，但是这事只有 kernel 知&lt;br /&gt;道，其它用户进程并不知道kernel read到什么了，普通用户进程根本访问不了 kernel space，无法和&lt;br /&gt;kernel 交流，只能被管理。因此read操作不会有问题。&lt;br /&gt;&lt;br /&gt;    kernel 启动时虽然建立了pte，可以直接访问所有非highmeme的物理内存，或者经过临时映射访问任何&lt;br /&gt;highmem位置的物理内存，但只是能访问，并没有独占权。当用户进程来申请页面时，只要有空闲页面，&lt;br /&gt;kernel 就一定要负责把页面分配给人家，kernel 不会妨碍用户进程占有页面。反过来，如果 kernel 自己&lt;br /&gt;想申请新的页面，而此时已经没有空闲页面可用了，那 kernel 没有权利把用户进程已经申请的页面给剥夺&lt;br /&gt;来自己用，kernel 必须要等，什么时候有用户进程释放页面了，什么时候 kernel 才能用，否则 kernel&lt;br /&gt;就得一直等着。为了避免产生这种情况，kernel 程序员就让 kernel 具有很好的管理能力: 平时把常用的&lt;br /&gt;页面放在 lru list 中，便于快速重用；同时设置一个空闲页面的阈值，当空闲页面数量太少时，kernel&lt;br /&gt;就要停下手中的工作，先去lru list中清理一些空闲页面出来。这样一来，kernel 即不会剥夺用户进程的&lt;br /&gt;页面，也尽量减少了自己死等用户进程释放页面的情况。&lt;br /&gt;&lt;br /&gt;    正是由于kernel程序员写的kernel能够控制应用程序员写的用户进程，因此kernel程序员比较难做。&lt;br /&gt;&lt;br /&gt;    对 proc 的修改很关键，容易出问题，因此不能直接在 production machine 上改，必须先在&lt;br /&gt;develop machine 上试验，而且只看文档是不够的，必须结合kernel源码来分析。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-1777151676698178704?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/1777151676698178704/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/07/memzone_09.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1777151676698178704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/1777151676698178704'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/07/memzone_09.html' title='MemZone 的阈值'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-5436646227543207006</id><published>2010-06-22T18:57:00.004+08:00</published><updated>2010-10-07T23:02:03.654+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 grams'/><title type='text'>几个洋人发明的词汇</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    这些词汇都来自国外，从出现到现在才200多年，却已经成为国家走向文明和强大的的必要条件，当今世&lt;br /&gt;界的主流。自从这些词汇出现后，"文明古国"就只有历史研究的意义了。无论国家的文明诞生多久，都是过&lt;br /&gt;去的事了，就算一个国家的起源历史很短也不会妨碍强大，Let bygones be bygones!&lt;br /&gt;&lt;br /&gt;    既然来自国外，就必须看看原始解释才能明白。这只是为了弄明白事情原委，不是拿点洋文去作秀，&lt;br /&gt;很多所谓的知识分子就喜欢作秀骗小孩儿，经常以背诵大段受世人唾弃的洋垃圾哲学为能事。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Constitution&lt;br /&gt;&lt;br /&gt;Merriar Webster dictionary:&lt;br /&gt;&lt;br /&gt;    the basic principles and laws of a nation, state, or social group that determine the&lt;br /&gt;powers and duties of the government and guarantee certain rights to the people in it&lt;br /&gt;&lt;br /&gt;    宪法，说白了，就是大家做人的底线，属于游戏中最基本的规则。你可以自私，可以贪得无厌，但是不&lt;br /&gt;能过底线，宪法就是这个底线。过去封建臣民有许多不能做的事，而对皇帝的限制就基本没有。宪法的出现&lt;br /&gt;就解决了这种不平等：无论你是总统还是平民，都必须遵守同一个法，就是宪法。为了让宪法得到真正的执&lt;br /&gt;行，就一定不能让总统去控制法院，国会中的人虽然多，权利不像总统那么集中，毕竟也不安全，所以还是&lt;br /&gt;让法院相对独立才可靠。&lt;br /&gt;&lt;br /&gt;    国会有立法权，但出来初稿后必须由总统拍板才算通过。同样，总统提名的官员要由国会拍板才算通过。&lt;br /&gt;总统他随便推荐，但是否用这个人最后要由国会说了算。如果没通过，那总统再推荐一个，如果还是没通过，&lt;br /&gt;那就继续。总统不傻，如果太多次通不过会很影响自己的声誉，因此，无论总统自己愿不愿意，他都不得不&lt;br /&gt;找一个真正有能力经得住国会检验的人。如果总统和国会双方僵持了，法院就介入了。这样就形成了美国的&lt;br /&gt;总统，国会，法院的三权分立。&lt;br /&gt;&lt;br /&gt;    道理是很简单了，就是两个人分食物，如果你先分了，就得我先挑。如果你想先挑，就得由我来分。整&lt;br /&gt;个过程必须分属于不同的人，这样就能保证无论分食物的人愿不愿意，他都会尽量分得公平，不然他后挑到&lt;br /&gt;的肯定是小份。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Congress&lt;br /&gt;&lt;br /&gt;Oxford Advanced Learner's Dictionary:&lt;br /&gt;&lt;br /&gt;    (in the US and some other countries) the name of the group of people who are elected to&lt;br /&gt;make laws, in the US consisting of the SENATE and the HOUSE OF REPRESENTATIVES:&lt;br /&gt;Congress will vote on the proposals tomorrow.&lt;br /&gt;&lt;br /&gt;    国会包括参议院和众议院。常规想自然是要平均，每个州有相同的代表。但这样一来，面积大人口多的&lt;br /&gt;州会感到单纯这样对他们很不公平。为此，在增加一个机构，人多的州代表也多点，人少的州代表就少点。&lt;br /&gt;&lt;br /&gt;    一共50个州，每个州选2名参议员，正好100人，组成参议院。&lt;br /&gt;    每个州再选出一部分人，大州人多些，小州人少些，共同组成众议院。&lt;br /&gt;&lt;br /&gt;    可见，即使这公平两字也要下功夫琢磨的，不同的角度，公平的意义就不同了，因此只能有相对的公平。&lt;br /&gt;也可以看出，美国那些开国的 Fathers 都是认真做事的人，天天在那喊口号的都是心术不正。&lt;br /&gt;&lt;br /&gt;    即使这样，还是不够安全，怕管理者共谋干坏事，那就来个媒体狗仔队，专门挖边边角角的丑事。让想&lt;br /&gt;做坏事的人提前死心，专注于工作。&lt;br /&gt;&lt;br /&gt;    但还是不够安全，媒体也和他们一起做坏事也是有可能的。管理者都在高墙深院之内，还有门卫保护，&lt;br /&gt;这种环境是可以安心做好事，但也是做坏事的天堂。为此老百姓在选出自己的代表的同时，还要提防那些代&lt;br /&gt;表日后变坏: 必要时我们得能上大街上光明正大的申诉，这样就有了 Demonstration。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Demonstration&lt;br /&gt;&lt;br /&gt;Oxford Advanced Learner's Dictionary:&lt;br /&gt;&lt;br /&gt;   (also informal demo especially in BrE) [C] ~ (against sb/sth) a public meeting or march at&lt;br /&gt;which people show that they are protesting against or supporting sb/sth:&lt;br /&gt;to take part in / go on a demonstration * to hold / stage a demonstration * mass demonstrations&lt;br /&gt;in support of the exiled leader * anti-government demonstrations * a peaceful / &lt;br /&gt;violent demonstration&lt;br /&gt;&lt;br /&gt;    有了上面的这些，物质上就有保证了，自己的钱不会随便就被人乱花。对animal来说，这已经足够了，&lt;br /&gt;但对有思想的人来说，这只是一部分。还要有精神层面的约定:&lt;br /&gt;&lt;br /&gt;1. 当遇到开心的节日时，总在家庆祝太狭隘了，不过瘾，还是上大街上人多有意思，因此就有了 Parade。&lt;br /&gt;2. 平时，兴趣接近的人在一起比较有话说，高山流水遇知音。这就有了 Association and Assembly。&lt;br /&gt;&lt;br /&gt;    有了上面的这两条，谈恋爱找对象是很容易的事，不必去相亲了。有了喜庆之事大家同喜，有了怨气也&lt;br /&gt;能马上发泄掉，不会积累成仇恨。社会上有了正气，人们心态就会平和，知道回报，私立大学的捐款远多过&lt;br /&gt;公立的。如果族类在优秀点，那人们都会体谅最底层的人，不忘记给小费。&lt;br /&gt;&lt;br /&gt;    当然，即使一个国家没有上面这两条rules，也会有一个一个的小圈子。特点就是：神秘。圈子之间都&lt;br /&gt;保持神秘，每个圈子都有违反道德的潜规则，很快就会促成整个社会的道德沦丧。人们都靠酒肉和金钱聚集&lt;br /&gt;到一起，明面的规定都是谎言，办芝麻大小的事也要靠关系。还会发生很多无法用正常想法解释的事，很多&lt;br /&gt;人都成精神病了。至于到底病人是精神病，还是说别人是精神病的医生他自己是精神病，没在社会上跑过的&lt;br /&gt;人是判断不出来的，即使能判断出来，但没深入那个圈子的人还是理解不透的。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Parade&lt;br /&gt;&lt;br /&gt;Oxford Advanced Learner's Dictionary:&lt;br /&gt;&lt;br /&gt;    a public celebration of a special day or event, usually with bands in the streets and&lt;br /&gt;decorated vehicles: the Lord Mayor's parade * St Patrick's Day parade in New York&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Assembly&lt;br /&gt;&lt;br /&gt;Oxford Advanced Learner's Dictionary:&lt;br /&gt;&lt;br /&gt;    the meeting together of a group of people for a particular purpose; a group of people who&lt;br /&gt;meet together for a particular purpose:&lt;br /&gt;    They were fighting for freedom of speech and freedom of assembly. * He was to address a&lt;br /&gt;public assembly on the issue. * an assembly point (= a place where people have been asked to&lt;br /&gt;meet) * the assembly rooms / hall&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Association&lt;br /&gt;&lt;br /&gt;Merriar Webster dictionary:&lt;br /&gt;&lt;br /&gt;    an organization of persons having a common interest : SOCIETY&lt;br /&gt;&lt;br /&gt;Longman Dictionary of Contemporary English:&lt;br /&gt;&lt;br /&gt;    an organization that consists of a group of people who have the same aims, do the same kind&lt;br /&gt;of work etc:  --the Association of Master Builders//    housing association//&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    100年前，中国人就追求D先生和S先生。&lt;br /&gt;&lt;br /&gt;    曾经采用了美国模式就是中山先生的三民主义: 民族，民权，民生。&lt;br /&gt;三民主义如今被说的太简略了！简略得让未能身临其境的人难以理解，还是原始的解释更容易懂:&lt;br /&gt;&lt;br /&gt;   National Independence&lt;br /&gt;   Freedom of Democracy&lt;br /&gt;   The Wellbeing of the people&lt;br /&gt;&lt;br /&gt;    第一条是效仿美国反抗英国殖民统治的独立战争，当时发表了著名的&amp;lt;&amp;lt;Declaration of Independence&amp;gt;&amp;gt;&lt;br /&gt;    第二条就得提到美国的 Statue of Liberty。自由女神上面如下文字：&lt;br /&gt;&lt;br /&gt;      Not like the brazen giant of Greek fame,&lt;br /&gt;      With conquering limbs astride from land to land;&lt;br /&gt;      Here at our sea-washed, sunset gates shall stand&lt;br /&gt;      A mighty woman with a torch, whose flame&lt;br /&gt;      Is the imprisoned lightning, and her name&lt;br /&gt;      Mother of Exiles. From her beacon-hand&lt;br /&gt;      Glows world-wide welcome; her mild eyes command&lt;br /&gt;      The air-bridged harbor that twin cities frame.&lt;br /&gt;      "Keep, ancient lands, your storied pomp!" cries she&lt;br /&gt;      ' With silent lips. "Give me your tired, your poor,&lt;br /&gt;      Your huddled masses yearning to breathe free,&lt;br /&gt;      The wretched refuse of your teeming shore.&lt;br /&gt;      Send these, the homeless, tempest-tossed to me,&lt;br /&gt;      I lift my lamp beside the golden door!"&lt;br /&gt;&lt;br /&gt;    文字说明了 free country 的含义，给予人们自由新鲜的空气，是一个包容的社会，这里会让人有幸福&lt;br /&gt;感和归宿感。这位女神使得一大批精英人士都逃到了美国，因为精英人士都有自己独到的见解和独立的人格，&lt;br /&gt;都不那么听话，这在专制国家是不被容忍的。这也被日后的事实所证明，当专制和民主对决的时候，无论是&lt;br /&gt;昔日强大的大清还是沙俄，都会败在小的不起眼的英国和日本手中，胜者属于民主这边。&lt;br /&gt;    &lt;br /&gt;    给予人们自私权利的社会，踏踏实实做事的，结果反而会有非常好的社会风气，还会有事先没预料到的&lt;br /&gt;意外的收获和惊喜；反到是那些高调打着解放全人类旗号暴力革命的，强调国不强调家的，形成的社会氛围&lt;br /&gt;都是极其畸形的，最终无一例外，都演变成了奴役全人类的罪恶。 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Democracy&lt;br /&gt;&lt;br /&gt;Longman Dictionary of Contemporary English:&lt;br /&gt;&lt;br /&gt;  1 [U] a system of government in which every citizen in the country can vote to elect its&lt;br /&gt;government officials:  --a return to democracy after 16 years of military rule//&lt;br /&gt;&lt;br /&gt;  2 [C] a country that has a government which has been elected by the people of the country:&lt;br /&gt;--a parliamentary democracy //  --Western democracies//&lt;br /&gt;&lt;br /&gt;  3 [U] a situation or system in which everyone is equal and has the right to vote, make&lt;br /&gt;decisions etc:    democratic//  --democracy within the trade unions//&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Freedom&lt;br /&gt;&lt;br /&gt;Longman Dictionary of Contemporary English:&lt;br /&gt;&lt;br /&gt;    the right to do what you want without being controlled or restricted by anyone:  liberty//&lt;br /&gt;--People here like their freedom and privacy.//  --the rights and freedoms of citizens//&lt;br /&gt;freedom to do sth//  --We do not have the freedom to do just what we like.//  --the freedom to&lt;br /&gt;vote//  freedom of speech/expression/choice etc (=the legal right to say what you want, choose&lt;br /&gt;your own religion etc) //  --The First Amendment guarantees freedom of expression.//&lt;br /&gt;individual/personal freedom //  --The government was accused of using the law to restrict&lt;br /&gt;individual freedom//  press/academic/political etc freedom //&lt;br /&gt;&lt;br /&gt;    100年后，中国人不在追求D先生和S先生。&lt;br /&gt;&lt;br /&gt;    有人说是找到了更好的宝贝，也有人说那宝贝就是瘟神，到哪哪就会有灾难。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-5436646227543207006?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/5436646227543207006/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/06/blog-post.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5436646227543207006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5436646227543207006'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/06/blog-post.html' title='几个洋人发明的词汇'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-6509828166499775014</id><published>2010-06-04T18:42:00.005+08:00</published><updated>2010-11-10T18:31:06.210+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Documentary</title><content type='html'>&lt;pre&gt;&lt;br /&gt;是个NHK迷，敬佩日本人工作的敬业，处事的公正，人文社会题材的大部分都看。&lt;br /&gt;&lt;br /&gt;1. 注重细节，几乎每部片都用CG技术把问题阐述的特别清晰易懂。&lt;br /&gt;&lt;br /&gt;2. 在聚焦某个话题之前，会介绍相关的背景。一方面避免唐突，能让人渐入佳境；另一方面也能让观众更加&lt;br /&gt;   清晰的了解事件的前因后果。如果介绍医疗，工科的人也能看懂整体; 要介绍银行卡技术，学文科的也能&lt;br /&gt;   明白大概的过程。具有开启民智的作用。&lt;br /&gt;&lt;br /&gt;3. 如果只针对现场报道，那成了新闻了，是BBC的风格，意义不大。NHK是请来专业的嘉宾到演播室，报道&lt;br /&gt;   现场结束后，片子并没有完，会有主持人和嘉宾的深入讨论分析，把事件的好处坏处都说到，非常理性。&lt;br /&gt;&lt;br /&gt;4. 政治题材的讨论比较温和，自己不会过多牵扯进去，保持中立。关键是镜头拍的已经很到位了，根本就无&lt;br /&gt;   需多说了，给观众留下了遐想的空间。&lt;br /&gt;&lt;br /&gt;5. 创作了很多精美的作曲。&lt;br /&gt;&lt;br /&gt;有了NHK，大陆的小学初中根本不用开地理历史课，只有专门学那个的才需要在高中阶段开课。&lt;br /&gt;而且大陆开的那些课不是废话连篇就是谎话连篇。地理还好，学的虽然枯燥累，毕竟还有点收获。而对历史&lt;br /&gt;来说不学只是0，学过之后反而成负值了。而自始自终CG的魅力，会让大学的图形图像专业火爆异常。&lt;br /&gt;&lt;br /&gt;从NHK中可以推断出日本学生的人文素质和分辨事物真伪的能力。由于不会给天真无邪的孩子洗脑，然后鼓动&lt;br /&gt;他们去做偏激的事，因此社会整体具有理性平和的氛围，温馨有人性可持续。&lt;br /&gt;&lt;br /&gt;比如报道中国一个初中将要毕业的姑娘家庭困难，上不起高中，节目播出后，日本人捐款使这个姑娘上了高&lt;br /&gt;中；一个中国农村的孩子做手术钱不够，节目播出后日本人给小孩捐款200多万人民币，但是电台为了不干涉&lt;br /&gt;别人的生活保持公正，没有把这么多的钱转给中国的小孩，而是都退回捐款人了。但却有个日本的老板亲自&lt;br /&gt;飞到中国来，给了小孩5万美元去做手术。这样的例子太多了，包括改革开放以来日本人给大陆2000多亿美元&lt;br /&gt;的经济援助。但在大陆这种事是不会有人积极报道的，当日本人的援助让中国农民吃上自来水的时候，把功&lt;br /&gt;劳拉到自己身上，30多年了大陆媒体对日本的援助只字不提。还有的捐款竟然让政府给贪污了，正是由于这&lt;br /&gt;种贪污行为，好处到不了百姓身上，近几年日本对华援助少了。早就该觉醒了，要捐给奋发图强有包容心知&lt;br /&gt;道感恩的人，捐给白眼狼是大错。以后如有捐款行为，必然要回报给NHK，NHK已经成了我的一个值得信赖的&lt;br /&gt;知心朋友。&lt;br /&gt;&lt;br /&gt;由于NHK公正尊重事实，有开启民智之功效，自然就被说谎成性的族类所不容。这种族类的国民大多数都无知&lt;br /&gt;劣等。中国底层老百姓并不像宣传的那样排斥日本人，包括被长期占领的东北。原因就是日本人当年侵华时&lt;br /&gt;期并不是宣传的那样坏。但是国内的学生除了被培养的会叫，连基本的是非都分辨不出来，被当炮灰推向前&lt;br /&gt;面还觉得很幸福。&lt;br /&gt;&lt;br /&gt;人文社会题材首选NHK，自然题材首选BBC和NG。BBC NG PBS Discovery具有欧美人的粗线条。只播放事件过&lt;br /&gt;程，是新闻性质，报道结束本片也就结束了，有流水帐的味道。但对于政治题材的报道尖锐入骨，的确具有&lt;br /&gt;美国资产阶级革命式的彻底性，不遮遮掩掩。介绍专门领域的科普题材不够细致，仅挑极个别的看。&lt;br /&gt;&lt;br /&gt;大陆和台湾个人制作的有好的，公映的都很明显的不公正，没法看。甚至有的大陆制片人跑到美国去造假，&lt;br /&gt;把当事人的谈话蓄意拼接，剪辑，使得呈现在屏幕面前的内容达到和当事人讲话表达的意思完全相反！这虽&lt;br /&gt;然不是输出革命，但是可以说是输出谎言，可能会影响大批的观众，比日常的说谎还要恶劣。&lt;br /&gt;&lt;br /&gt;最喜欢主持人国谷裕子，言谈举止真有女人魅力，可惜是57年的，要年轻20年就好了，就可以在屏幕上陪伴&lt;br /&gt;我走完后半生了。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-6509828166499775014?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/6509828166499775014/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/06/documentary.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/6509828166499775014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/6509828166499775014'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/06/documentary.html' title='Documentary'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-2533463165560997379</id><published>2010-04-26T17:16:00.001+08:00</published><updated>2010-04-26T21:11:48.297+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>signal</title><content type='html'>&lt;pre&gt;&lt;br /&gt;一个用户进程执行时，如果产生了信号，用户程序被打断，kernel会把用户进程的register内容保存到该进&lt;br /&gt;程的kernel stack中，kernel还会执行其它工作，还会设定sigmask，然后返回用户态去执行sig_handler，&lt;br /&gt;sig_handler执行结束后，恢复被信号打断的用户进程的执行。&lt;br /&gt;&lt;br /&gt;一般的用户进程执行系统调用的需求是: user process -&amp;gt; kernel mode -&amp;gt; user process&lt;br /&gt;解决方法是把用户进程的ss, sp, cs, eip等值保存到该进程的kernel stack中，返回到user mode时恢复出&lt;br /&gt;来就行了。&lt;br /&gt;&lt;br /&gt;而信号处理的需求是: user process -&amp;gt; kernel mode -&amp;gt; sig_handler(user mode) -&amp;gt; user process&lt;br /&gt;&lt;br /&gt;也是先把用户进程的ss, sp, cs, eip等值保存到该进程的kernel stack中，在返回到user mode执行&lt;br /&gt;sig_handler时就要特别处理了: 一旦返回到user mode，进程的kernel stack可能被破坏，那将来&lt;br /&gt;sig_handler结束后，用户进程就没法恢复状态继续运行了。为了使用户进程不被打扰，还要undo sigmask。&lt;br /&gt;&lt;br /&gt;Linux的解决方法是:&lt;br /&gt;&lt;br /&gt;返回user mode执行sig_handler之前，把kernel stack中的上下文copy到当前进程的user stack中，在建立&lt;br /&gt;sig_handler的stack环境时，将sigreturn()的地址插入到stack中，当sig_handler执行完毕后，就会执行&lt;br /&gt;sigreturn()重新进入kernel mode。sigreturn()把保存的内容重新填入kernel stack，undo sigmask。这&lt;br /&gt;样返回用户态之后，用户进程就能继续正常执行了。&lt;br /&gt;&lt;br /&gt;man sigreturn:&lt;br /&gt;&lt;br /&gt;When  the  Linux  kernel creates the stack frame for a signal handler, a call to sigreturn() is&lt;br /&gt;inserted into the stack frame so that upon return from the signal handler, sigreturn() will  be&lt;br /&gt;called.&lt;br /&gt;&lt;br /&gt;This  sigreturn()  call  undoes  everything  that  was done—changing the process’s signal mask,&lt;br /&gt;switching stacks (see sigaltstack(2))—in order to invoke the signal handler:  it  restores  the&lt;br /&gt;process’s  signal mask, switches stacks, and restores the process’s context (registers, proces-&lt;br /&gt;sor flags), so that the process directly resumes execution at the point  where  it  was  inter-&lt;br /&gt;rupted by the signal.&lt;br /&gt;&lt;br /&gt;这样信号处理的过程是: &lt;br /&gt;user process -&amp;gt; kernel mode -&amp;gt; sig_handler(user mode) -&amp;gt; sigreturn(kernel mode) -&amp;gt; user process&lt;br /&gt;&lt;br /&gt;用户态对编程sigaction()对应kernel中是do_sigaction()，man sigaction 对照。&lt;br /&gt;&lt;br /&gt;int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)&lt;br /&gt;{&lt;br /&gt;        struct task_struct *t = current;&lt;br /&gt;        struct k_sigaction *k;&lt;br /&gt;        sigset_t mask;&lt;br /&gt;&lt;br /&gt;        if (!valid_signal(sig) || sig &amp;lt; 1 || (act &amp;&amp; sig_kernel_only(sig)))&lt;br /&gt;                return -EINVAL;&lt;br /&gt;&lt;br /&gt;        k = &amp;t-&amp;gt;sighand-&amp;gt;action[sig-1];&lt;br /&gt;&lt;br /&gt;        spin_lock_irq(&amp;current-&amp;gt;sighand-&amp;gt;siglock);&lt;br /&gt;        if (oact)&lt;br /&gt;                *oact = *k;&lt;br /&gt;&lt;br /&gt;        if (act) {&lt;br /&gt;                sigdelsetmask(&amp;act-&amp;gt;sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP));&lt;br /&gt;                *k = *act;&lt;br /&gt;                /*&lt;br /&gt;                 * POSIX 3.3.1.3:&lt;br /&gt;                 *  "Setting a signal action to SIG_IGN for a signal that is&lt;br /&gt;                 *   pending shall cause the pending signal to be discarded,&lt;br /&gt;                 *   whether or not it is blocked."&lt;br /&gt;                 *&lt;br /&gt;                 *  "Setting a signal action to SIG_DFL for a signal that is&lt;br /&gt;                 *   pending and whose default action is to ignore the signal&lt;br /&gt;                 *   (for example, SIGCHLD), shall cause the pending signal to&lt;br /&gt;                 *   be discarded, whether or not it is blocked"&lt;br /&gt;                 */&lt;br /&gt;                if (sig_handler_ignored(sig_handler(t, sig), sig)) {&lt;br /&gt;                        sigemptyset(&amp;mask);&lt;br /&gt;                        sigaddset(&amp;mask, sig);&lt;br /&gt;                        rm_from_queue_full(&amp;mask, &amp;t-&amp;gt;signal-&amp;gt;shared_pending);&lt;br /&gt;                        do {&lt;br /&gt;                                rm_from_queue_full(&amp;mask, &amp;t-&amp;gt;pending);&lt;br /&gt;                                t = next_thread(t);&lt;br /&gt;                        } while (t != current);&lt;br /&gt;                }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        spin_unlock_irq(&amp;current-&amp;gt;sighand-&amp;gt;siglock);&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;SIGKILL 和 SIGSTOP 特殊，用户不能改变它们的disposition，所以不能对它们两个设置sig_handler()&lt;br /&gt;这和man 7 signal的说明一致:&lt;br /&gt;&lt;br /&gt;#define sig_kernel_only(sig) \&lt;br /&gt;        (((sig) &amp;lt; SIGRTMIN) &amp;&amp; siginmask(sig, SIG_KERNEL_ONLY_MASK))&lt;br /&gt;&lt;br /&gt;#define SIG_KERNEL_ONLY_MASK (\&lt;br /&gt;        rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))&lt;br /&gt;&lt;br /&gt;关键就是 struct k_sigaction，里面有sig_handler()，mask等，kernel处理时会用到。&lt;br /&gt;&lt;br /&gt;struct sighand_struct {&lt;br /&gt;        atomic_t                count;&lt;br /&gt;        struct k_sigaction      action[_NSIG];&lt;br /&gt;        spinlock_t              siglock;&lt;br /&gt;        wait_queue_head_t       signalfd_wqh;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct k_sigaction {&lt;br /&gt;        struct sigaction sa;    &lt;br /&gt;};      &lt;br /&gt;&lt;br /&gt;struct sigaction {&lt;br /&gt;        __sighandler_t sa_handler;&lt;br /&gt;        unsigned long sa_flags;         &lt;br /&gt;        __sigrestore_t sa_restorer;&lt;br /&gt;        sigset_t sa_mask;               /* mask last for extensibility */&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;假设kernel编译成 CONFIG_PREEMPT_NONE&lt;br /&gt;&lt;br /&gt;信号的generate: send_sig()，会设置 TIF_SIGPENDING 。&lt;br /&gt;&lt;br /&gt;信号的检测时机: &lt;br /&gt;1。目标进程从kernel mode返回user mode时，如果检测到 TIF_SIGPENDING ，会调用 do_signal()来处理。&lt;br /&gt;2。目标进程处于 TASK_INTERRUPTIBLE 状态，如果检测到 TIF_SIGPENDING ，会退出wait状态:&lt;br /&gt;&lt;br /&gt;267 /**&lt;br /&gt;268  * wait_event_interruptible - sleep until a condition gets true&lt;br /&gt;269  * @wq: the waitqueue to wait on&lt;br /&gt;270  * @condition: a C expression for the event to wait for&lt;br /&gt;271  *&lt;br /&gt;272  * The process is put to sleep (TASK_INTERRUPTIBLE) until the&lt;br /&gt;273  * @condition evaluates to true or a signal is received.&lt;br /&gt;274  * The @condition is checked each time the waitqueue @wq is woken up.&lt;br /&gt;275  *&lt;br /&gt;276  * wake_up() has to be called after changing any variable that could&lt;br /&gt;277  * change the result of the wait condition.&lt;br /&gt;278  *&lt;br /&gt;279  * The function will return -ERESTARTSYS if it was interrupted by a&lt;br /&gt;280  * signal and 0 if @condition evaluated to true.&lt;br /&gt;281  */&lt;br /&gt;282 #define wait_event_interruptible(wq, condition)                         \&lt;br /&gt;283 ({                                                                      \&lt;br /&gt;284         int __ret = 0;                                                  \&lt;br /&gt;285         if (!(condition))                                               \&lt;br /&gt;286                 __wait_event_interruptible(wq, condition, __ret);       \&lt;br /&gt;287         __ret;                                                          \&lt;br /&gt;288 })&lt;br /&gt;&lt;br /&gt;249 #define __wait_event_interruptible(wq, condition, ret)                  \&lt;br /&gt;250 do {                                                                    \&lt;br /&gt;251         DEFINE_WAIT(__wait);                                            \&lt;br /&gt;252                                                                         \&lt;br /&gt;253         for (;;) {                                                      \&lt;br /&gt;254                 prepare_to_wait(&amp;wq, &amp;__wait, TASK_INTERRUPTIBLE);      \&lt;br /&gt;255                 if (condition)                                          \&lt;br /&gt;256                         break;                                          \&lt;br /&gt;257                 if (!signal_pending(current)) {                         \&lt;br /&gt;258                         schedule();                                     \&lt;br /&gt;259                         continue;                                       \&lt;br /&gt;260                 }                                                       \&lt;br /&gt;261                 ret = -ERESTARTSYS;                                     \&lt;br /&gt;262                 break;                                                  \&lt;br /&gt;263         }                                                               \&lt;br /&gt;264         finish_wait(&amp;wq, &amp;__wait);                                      \&lt;br /&gt;265 } while (0)&lt;br /&gt;&lt;br /&gt;一。用户态进程发信号给其它进程&lt;br /&gt;&lt;br /&gt;对于 kill sigqueue 这类用户进程通过系统调用发送的信号，最终都是调用 do_send_sig_info() 系列，&lt;br /&gt;所以只需走一遍 send_sig()，man 7 signal 对照&lt;br /&gt;&lt;br /&gt;看看kill在kernel中的实现，man 2 kill 对照。&lt;br /&gt;$ vi -t send_sig      对应kill的kernel source就在这个文件里:&lt;br /&gt;&lt;br /&gt;SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)&lt;br /&gt;{&lt;br /&gt;        struct siginfo info;&lt;br /&gt;&lt;br /&gt;        info.si_signo = sig;&lt;br /&gt;        info.si_errno = 0;&lt;br /&gt;        info.si_code = SI_USER;&lt;br /&gt;        info.si_pid = task_tgid_vnr(current);&lt;br /&gt;        info.si_uid = current_uid();&lt;br /&gt;&lt;br /&gt;        return kill_something_info(sig, &amp;info, pid);   // will call do_send_sig_info()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;send_sig()更改接收信号的进程的task_struct中的相关field，struct sigqueue等，设置 TIF_SIGPENDING。&lt;br /&gt;调用try_to_wake_up()唤醒目标进程，比如处于 TASK_INTERRUPTIBLE 状态的进程，看能否设置&lt;br /&gt;TIF_NEEDRESCHED ，能设置就设置。这样current从kernel mode返回到user mode时，如果目标进程比&lt;br /&gt;current优先级高，就会发生调度，目标进程开始执行，当返回到user mode时就会处理该信号。&lt;br /&gt;&lt;br /&gt;过程挺多，必须要先理解schedule原理才行。平时kill一个进程很快就没了，以为对信号的处理是实时的。&lt;br /&gt;看了源码就知道对信号的处理并不是实时的。&lt;br /&gt;&lt;br /&gt;send_sig() -&amp;gt; send_sig_info() -&amp;gt; do_send_sig_info() -&amp;gt; send_signal() -&amp;gt; __send_signal():&lt;br /&gt;&lt;br /&gt;864 static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,&lt;br /&gt;865                         int group, int from_ancestor_ns)&lt;br /&gt;866 {&lt;br /&gt;867         struct sigpending *pending;&lt;br /&gt;868         struct sigqueue *q;&lt;br /&gt;869         int override_rlimit;&lt;br /&gt;870 &lt;br /&gt;871         trace_signal_generate(sig, info, t);&lt;br /&gt;872 &lt;br /&gt;873         assert_spin_locked(&amp;t-&amp;gt;sighand-&amp;gt;siglock);&lt;br /&gt;874 &lt;br /&gt;875         if (!prepare_signal(sig, t, from_ancestor_ns))&lt;br /&gt;876                 return 0;&lt;br /&gt;877 &lt;br /&gt;878         pending = group ? &amp;t-&amp;gt;signal-&amp;gt;shared_pending : &amp;t-&amp;gt;pending;&lt;br /&gt;879         /*&lt;br /&gt;880          * Short-circuit ignored signals and support queuing&lt;br /&gt;881          * exactly one non-rt signal, so that we can get more&lt;br /&gt;882          * detailed information about the cause of the signal.&lt;br /&gt;883          */&lt;br /&gt;884         if (legacy_queue(pending, sig))&lt;br /&gt;885                 return 0;&lt;br /&gt;886         /*&lt;br /&gt;887          * fast-pathed signals for kernel-internal things like SIGSTOP&lt;br /&gt;888          * or SIGKILL.&lt;br /&gt;889          */&lt;br /&gt;890         if (info == SEND_SIG_FORCED)&lt;br /&gt;891                 goto out_set;&lt;br /&gt;892 &lt;br /&gt;893         /* Real-time signals must be queued if sent by sigqueue, or&lt;br /&gt;894            some other real-time mechanism.  It is implementation&lt;br /&gt;895            defined whether kill() does so.  We attempt to do so, on&lt;br /&gt;896            the principle of least surprise, but since kill is not&lt;br /&gt;897            allowed to fail with EAGAIN when low on memory we just&lt;br /&gt;898            make sure at least one signal gets delivered and don't&lt;br /&gt;899            pass on the info struct.  */&lt;br /&gt;900 &lt;br /&gt;901         if (sig &amp;lt; SIGRTMIN)&lt;br /&gt;902                 override_rlimit = (is_si_special(info) || info-&amp;gt;si_code &amp;gt;= 0);&lt;br /&gt;903         else&lt;br /&gt;904                 override_rlimit = 0;&lt;br /&gt;905 &lt;br /&gt;906         q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,&lt;br /&gt;907                 override_rlimit);&lt;br /&gt;908         if (q) {&lt;br /&gt;909                 list_add_tail(&amp;q-&amp;gt;list, &amp;pending-&amp;gt;list);&lt;br /&gt;910                 switch ((unsigned long) info) {&lt;br /&gt;911                 case (unsigned long) SEND_SIG_NOINFO:&lt;br /&gt;912                         q-&amp;gt;info.si_signo = sig;&lt;br /&gt;913                         q-&amp;gt;info.si_errno = 0;&lt;br /&gt;914                         q-&amp;gt;info.si_code = SI_USER;&lt;br /&gt;915                         q-&amp;gt;info.si_pid = task_tgid_nr_ns(current,&lt;br /&gt;916                                                         task_active_pid_ns(t));&lt;br /&gt;917                         q-&amp;gt;info.si_uid = current_uid();&lt;br /&gt;918                         break;&lt;br /&gt;919                 case (unsigned long) SEND_SIG_PRIV:&lt;br /&gt;920                         q-&amp;gt;info.si_signo = sig;&lt;br /&gt;921                         q-&amp;gt;info.si_errno = 0;&lt;br /&gt;922                         q-&amp;gt;info.si_code = SI_KERNEL;&lt;br /&gt;923                         q-&amp;gt;info.si_pid = 0;&lt;br /&gt;924                         q-&amp;gt;info.si_uid = 0;&lt;br /&gt;925                         break;&lt;br /&gt;926                 default:&lt;br /&gt;927                         copy_siginfo(&amp;q-&amp;gt;info, info);&lt;br /&gt;928                         if (from_ancestor_ns)&lt;br /&gt;929                                 q-&amp;gt;info.si_pid = 0;&lt;br /&gt;930                         break;&lt;br /&gt;931                 }&lt;br /&gt;932         } else if (!is_si_special(info)) {&lt;br /&gt;933                 if (sig &amp;gt;= SIGRTMIN &amp;&amp; info-&amp;gt;si_code != SI_USER) {&lt;br /&gt;934                         /*&lt;br /&gt;935                          * Queue overflow, abort.  We may abort if the&lt;br /&gt;936                          * signal was rt and sent by user using something&lt;br /&gt;937                          * other than kill().&lt;br /&gt;938                          */&lt;br /&gt;939                         trace_signal_overflow_fail(sig, group, info);&lt;br /&gt;940                         return -EAGAIN;&lt;br /&gt;941                 } else {&lt;br /&gt;942                         /*&lt;br /&gt;943                          * This is a silent loss of information.  We still&lt;br /&gt;944                          * send the signal, but the *info bits are lost.&lt;br /&gt;945                          */&lt;br /&gt;946                         trace_signal_lose_info(sig, group, info);&lt;br /&gt;947                 }&lt;br /&gt;948         }&lt;br /&gt;949 &lt;br /&gt;950 out_set:&lt;br /&gt;951         signalfd_notify(t, sig);&lt;br /&gt;952         sigaddset(&amp;pending-&amp;gt;signal, sig);&lt;br /&gt;953         complete_signal(sig, t, group);&lt;br /&gt;954         return 0;&lt;br /&gt;955 }&lt;br /&gt;&lt;br /&gt;prepare_signal()是处理SIGSTOP/SIGCONT SIG_IGN的，不进去。&lt;br /&gt;&lt;br /&gt;分配struct sigqueue，填充info，保存产生的信号信息。将来处理信号的时候会到这来找。&lt;br /&gt;&lt;br /&gt;struct sigqueue {&lt;br /&gt;        struct list_head list;&lt;br /&gt;        int flags;&lt;br /&gt;        siginfo_t info;&lt;br /&gt;        struct user_struct *user;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;由SEND_SIG_NOINFO SI_KERNEL 找到一些定义:&lt;br /&gt;&lt;br /&gt;#define SEND_SIG_NOINFO ((struct siginfo *) 0)&lt;br /&gt;#define SEND_SIG_PRIV   ((struct siginfo *) 1)&lt;br /&gt;#define SEND_SIG_FORCED ((struct siginfo *) 2)&lt;br /&gt;&lt;br /&gt;/*                      &lt;br /&gt; * si_code values       &lt;br /&gt; * Digital reserves positive values for kernel-generated signals.&lt;br /&gt; */                     &lt;br /&gt;#define SI_USER         0               /* sent by kill, sigsend, raise */&lt;br /&gt;#define SI_KERNEL       0x80            /* sent by the kernel from somewhere */&lt;br /&gt;#define SI_QUEUE        -1              /* sent by sigqueue */&lt;br /&gt;#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */&lt;br /&gt;#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */&lt;br /&gt;#define SI_ASYNCIO      -4              /* sent by AIO completion */&lt;br /&gt;#define SI_SIGIO        -5              /* sent by queued SIGIO */&lt;br /&gt;#define SI_TKILL        -6              /* sent by tkill system call */&lt;br /&gt;#define SI_DETHREAD     -7              /* sent by execve() killing subsidiary threads */&lt;br /&gt;&lt;br /&gt;由 SI_KERNEL 注释看出，有些信号是kernel本身发出的。&lt;br /&gt;&lt;br /&gt;末尾的signalfd_notify()和complete_signal()都会调用try_to_wake_up()&lt;br /&gt;complete_signal()会设置 TIF_SIGPENDING。&lt;br /&gt;&lt;br /&gt;需要注意的是，即使信号是SIGKILL，也不能立即杀掉目标进程，还是要等目标进程被调度执行，然后&lt;br /&gt;从kernel mode 返回 user mode 时才能杀掉。&lt;br /&gt;&lt;br /&gt;__send_signal() -&amp;gt; complete_signal()&lt;br /&gt;&lt;br /&gt;783 static void complete_signal(int sig, struct task_struct *p, int group)&lt;br /&gt;784 {&lt;br /&gt;785         struct signal_struct *signal = p-&amp;gt;signal;&lt;br /&gt;786         struct task_struct *t;&lt;br /&gt;787 &lt;br /&gt;788         /*&lt;br /&gt;789          * Now find a thread we can wake up to take the signal off the queue.&lt;br /&gt;790          *&lt;br /&gt;791          * If the main thread wants the signal, it gets first crack.&lt;br /&gt;792          * Probably the least surprising to the average bear.&lt;br /&gt;793          */&lt;br /&gt;794         if (wants_signal(sig, p))&lt;br /&gt;795                 t = p;&lt;br /&gt;796         else if (!group || thread_group_empty(p))&lt;br /&gt;797                 /*&lt;br /&gt;798                  * There is just one thread and it does not need to be woken.&lt;br /&gt;799                  * It will dequeue unblocked signals before it runs again.&lt;br /&gt;800                  */&lt;br /&gt;801                 return;&lt;br /&gt;802         else {&lt;br /&gt;803                 /*&lt;br /&gt;804                  * Otherwise try to find a suitable thread.&lt;br /&gt;805                  */&lt;br /&gt;806                 t = signal-&amp;gt;curr_target;&lt;br /&gt;807                 while (!wants_signal(sig, t)) {&lt;br /&gt;808                         t = next_thread(t);&lt;br /&gt;809                         if (t == signal-&amp;gt;curr_target)&lt;br /&gt;810                                 /*&lt;br /&gt;811                                  * No thread needs to be woken.&lt;br /&gt;812                                  * Any eligible threads will see&lt;br /&gt;813                                  * the signal in the queue soon.&lt;br /&gt;814                                  */&lt;br /&gt;815                                 return;&lt;br /&gt;816                 }&lt;br /&gt;817                 signal-&amp;gt;curr_target = t;&lt;br /&gt;818         }&lt;br /&gt;819 &lt;br /&gt;820         /*&lt;br /&gt;821          * Found a killable thread.  If the signal will be fatal,&lt;br /&gt;822          * then start taking the whole group down immediately.&lt;br /&gt;823          */&lt;br /&gt;824         if (sig_fatal(p, sig) &amp;&amp;&lt;br /&gt;825             !(signal-&amp;gt;flags &amp; (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) &amp;&amp;&lt;br /&gt;826             !sigismember(&amp;t-&amp;gt;real_blocked, sig) &amp;&amp;&lt;br /&gt;827             (sig == SIGKILL ||&lt;br /&gt;828              !tracehook_consider_fatal_signal(t, sig))) {&lt;br /&gt;829                 /*&lt;br /&gt;830                  * This signal will be fatal to the whole group.&lt;br /&gt;831                  */&lt;br /&gt;832                 if (!sig_kernel_coredump(sig)) {&lt;br /&gt;833                         /*&lt;br /&gt;834                          * Start a group exit and wake everybody up.&lt;br /&gt;835                          * This way we don't have other threads&lt;br /&gt;836                          * running and doing things after a slower&lt;br /&gt;837                          * thread has the fatal signal pending.&lt;br /&gt;838                          */&lt;br /&gt;839                         signal-&amp;gt;flags = SIGNAL_GROUP_EXIT;&lt;br /&gt;840                         signal-&amp;gt;group_exit_code = sig;&lt;br /&gt;841                         signal-&amp;gt;group_stop_count = 0;&lt;br /&gt;842                         t = p;&lt;br /&gt;843                         do {&lt;br /&gt;844                                 sigaddset(&amp;t-&amp;gt;pending.signal, SIGKILL);&lt;br /&gt;845                                 signal_wake_up(t, 1); // cant terminate process immediately&lt;br /&gt;846                         } while_each_thread(p, t);&lt;br /&gt;847                         return;&lt;br /&gt;848                 }&lt;br /&gt;849         }&lt;br /&gt;850 &lt;br /&gt;851         /*&lt;br /&gt;852          * The signal is already in the shared-pending queue.&lt;br /&gt;853          * Tell the chosen thread to wake up and dequeue it.&lt;br /&gt;854          */&lt;br /&gt;855         signal_wake_up(t, sig == SIGKILL);&lt;br /&gt;856         return;&lt;br /&gt;857 }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Test if P wants to take SIG.  After we've checked all threads with this,&lt;br /&gt; * it's equivalent to finding no threads not blocking SIG.  Any threads not&lt;br /&gt; * blocking SIG were ruled out because they are not running and already&lt;br /&gt; * have pending signals.  Such threads will dequeue from the shared queue&lt;br /&gt; * as soon as they're available, so putting the signal on the shared queue&lt;br /&gt; * will be equivalent to sending it to one such thread.&lt;br /&gt; */&lt;br /&gt;static inline int wants_signal(int sig, struct task_struct *p)&lt;br /&gt;{&lt;br /&gt;        if (sigismember(&amp;p-&amp;gt;blocked, sig))&lt;br /&gt;                return 0;&lt;br /&gt;        if (p-&amp;gt;flags &amp; PF_EXITING)&lt;br /&gt;                return 0;&lt;br /&gt;        if (sig == SIGKILL)&lt;br /&gt;                return 1;&lt;br /&gt;        if (task_is_stopped_or_traced(p))&lt;br /&gt;                return 0;&lt;br /&gt;        return task_curr(p) || !signal_pending(p);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;__send_signal() -&amp;gt; complete_signal() -&amp;gt; signal_wake_up()&lt;br /&gt;&lt;br /&gt;528 /*&lt;br /&gt;529  * Tell a process that it has a new active signal..&lt;br /&gt;530  *&lt;br /&gt;531  * NOTE! we rely on the previous spin_lock to&lt;br /&gt;532  * lock interrupts for us! We can only be called with&lt;br /&gt;533  * "siglock" held, and the local interrupt must&lt;br /&gt;534  * have been disabled when that got acquired!&lt;br /&gt;535  *&lt;br /&gt;536  * No need to set need_resched since signal event passing&lt;br /&gt;537  * goes through -&amp;gt;blocked&lt;br /&gt;538  */&lt;br /&gt;539 void signal_wake_up(struct task_struct *t, int resume)&lt;br /&gt;540 {&lt;br /&gt;541         unsigned int mask;&lt;br /&gt;542 &lt;br /&gt;543         set_tsk_thread_flag(t, TIF_SIGPENDING);     // here&lt;br /&gt;544 &lt;br /&gt;545         /*&lt;br /&gt;546          * For SIGKILL, we want to wake it up in the stopped/traced/killable&lt;br /&gt;547          * case. We don't check t-&amp;gt;state here because there is a race with it&lt;br /&gt;548          * executing another processor and just now entering stopped state.&lt;br /&gt;549          * By using wake_up_state, we ensure the process will wake up and&lt;br /&gt;550          * handle its death signal.&lt;br /&gt;551          */&lt;br /&gt;552         mask = TASK_INTERRUPTIBLE;&lt;br /&gt;553         if (resume)&lt;br /&gt;554                 mask |= TASK_WAKEKILL;&lt;br /&gt;555         if (!wake_up_state(t, mask))     // try_to_wake_up()&lt;br /&gt;556                 kick_process(t);&lt;br /&gt;557 }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;目标进程对信号的检测和处理:&lt;br /&gt;&lt;br /&gt;假设目标进程已被scheduler选中，当目标进程从 kernel mode 返回到 user mode 时，会检验到&lt;br /&gt;TIF_SIGPENDING，从而进行处理。&lt;br /&gt;&lt;br /&gt;350 ret_from_exception:&lt;br /&gt;351         preempt_stop(CLBR_ANY)&lt;br /&gt;352 ret_from_intr:&lt;br /&gt;353         GET_THREAD_INFO(%ebp)&lt;br /&gt;354 check_userspace:&lt;br /&gt;355         movl PT_EFLAGS(%esp), %eax      # mix EFLAGS and CS&lt;br /&gt;356         movb PT_CS(%esp), %al&lt;br /&gt;357         andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax&lt;br /&gt;358         cmpl $USER_RPL, %eax&lt;br /&gt;359         jb resume_kernel                # not returning to v8086 or userspace&lt;br /&gt;360 &lt;br /&gt;361 ENTRY(resume_userspace)&lt;br /&gt;362         LOCKDEP_SYS_EXIT&lt;br /&gt;363         DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt&lt;br /&gt;364                                         # setting need_resched or sigpending&lt;br /&gt;365                                         # between sampling and the iret&lt;br /&gt;366         TRACE_IRQS_OFF&lt;br /&gt;367         movl TI_flags(%ebp), %ecx&lt;br /&gt;368         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on&lt;br /&gt;369                                         # int/exception return?&lt;br /&gt;370         jne work_pending&lt;br /&gt;371         jmp restore_all&lt;br /&gt;372 END(ret_from_exception)&lt;br /&gt;&lt;br /&gt;            ......&lt;br /&gt;&lt;br /&gt;638 work_pending:                           &lt;br /&gt;639         testb $_TIF_NEED_RESCHED, %cl&lt;br /&gt;640         jz work_notifysig&lt;br /&gt;641 work_resched:&lt;br /&gt;642         call schedule&lt;br /&gt;643         LOCKDEP_SYS_EXIT&lt;br /&gt;644         DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt&lt;br /&gt;645                                         # setting need_resched or sigpending&lt;br /&gt;646                                         # between sampling and the iret&lt;br /&gt;647         TRACE_IRQS_OFF&lt;br /&gt;648         movl TI_flags(%ebp), %ecx&lt;br /&gt;649         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other&lt;br /&gt;650                                         # than syscall tracing?&lt;br /&gt;651         jz restore_all&lt;br /&gt;652         testb $_TIF_NEED_RESCHED, %cl&lt;br /&gt;653         jnz work_resched&lt;br /&gt;654         &lt;br /&gt;655 work_notifysig:                         # deal with pending signals and&lt;br /&gt;656                                         # notify-resume requests&lt;br /&gt;657 #ifdef CONFIG_VM86&lt;br /&gt;658         testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)&lt;br /&gt;659         movl %esp, %eax&lt;br /&gt;660         jne work_notifysig_v86          # returning to kernel-space or&lt;br /&gt;661                                         # vm86-space&lt;br /&gt;662         xorl %edx, %edx&lt;br /&gt;663         call do_notify_resume           // here&lt;br /&gt;664         jmp resume_userspace_sig&lt;br /&gt;665 &lt;br /&gt;666         ALIGN&lt;br /&gt;667 work_notifysig_v86:&lt;br /&gt;             ......&lt;br /&gt;&lt;br /&gt;834 /*&lt;br /&gt;835  * notification of userspace execution resumption&lt;br /&gt;836  * - triggered by the TIF_WORK_MASK flags&lt;br /&gt;837  */&lt;br /&gt;838 void&lt;br /&gt;839 do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)&lt;br /&gt;840 {&lt;br /&gt;841 #ifdef CONFIG_X86_MCE&lt;br /&gt;842         /* notify userspace of pending MCEs */&lt;br /&gt;843         if (thread_info_flags &amp; _TIF_MCE_NOTIFY)&lt;br /&gt;844                 mce_notify_process();&lt;br /&gt;845 #endif /* CONFIG_X86_64 &amp;&amp; CONFIG_X86_MCE */&lt;br /&gt;846 &lt;br /&gt;847         /* deal with pending signal delivery */&lt;br /&gt;848         if (thread_info_flags &amp; _TIF_SIGPENDING)&lt;br /&gt;849                 do_signal(regs);&lt;br /&gt;850 &lt;br /&gt;851         if (thread_info_flags &amp; _TIF_NOTIFY_RESUME) {&lt;br /&gt;852                 clear_thread_flag(TIF_NOTIFY_RESUME);&lt;br /&gt;853                 tracehook_notify_resume(regs);&lt;br /&gt;854                 if (current-&amp;gt;replacement_session_keyring)&lt;br /&gt;855                         key_replace_session_keyring();&lt;br /&gt;856         }&lt;br /&gt;857         if (thread_info_flags &amp; _TIF_USER_RETURN_NOTIFY)&lt;br /&gt;858                 fire_user_return_notifiers();&lt;br /&gt;859 &lt;br /&gt;860 #ifdef CONFIG_X86_32&lt;br /&gt;861         clear_thread_flag(TIF_IRET);&lt;br /&gt;862 #endif /* CONFIG_X86_32 */&lt;br /&gt;863 }                                        &lt;br /&gt;&lt;br /&gt;do_notify_resume() -&amp;gt; do_signal()&lt;br /&gt;&lt;br /&gt;764 /*&lt;br /&gt;765  * Note that 'init' is a special process: it doesn't get signals it doesn't&lt;br /&gt;766  * want to handle. Thus you cannot kill init even with a SIGKILL even by&lt;br /&gt;767  * mistake.&lt;br /&gt;768  */&lt;br /&gt;769 static void do_signal(struct pt_regs *regs)&lt;br /&gt;770 {&lt;br /&gt;771         struct k_sigaction ka;&lt;br /&gt;772         siginfo_t info;&lt;br /&gt;773         int signr;&lt;br /&gt;774         sigset_t *oldset;&lt;br /&gt;775 &lt;br /&gt;776         /*&lt;br /&gt;777          * We want the common case to go fast, which is why we may in certain&lt;br /&gt;778          * cases get here from kernel mode. Just return without doing anything&lt;br /&gt;779          * if so.&lt;br /&gt;780          * X86_32: vm86 regs switched out by assembly code before reaching&lt;br /&gt;781          * here, so testing against kernel CS suffices.&lt;br /&gt;782          */&lt;br /&gt;783         if (!user_mode(regs))&lt;br /&gt;784                 return;&lt;br /&gt;785 &lt;br /&gt;786         if (current_thread_info()-&amp;gt;status &amp; TS_RESTORE_SIGMASK)&lt;br /&gt;787                 oldset = &amp;current-&amp;gt;saved_sigmask;&lt;br /&gt;788         else&lt;br /&gt;789                 oldset = &amp;current-&amp;gt;blocked;&lt;br /&gt;790 &lt;br /&gt;791         signr = get_signal_to_deliver(&amp;info, &amp;ka, regs, NULL);&lt;br /&gt;792         if (signr &amp;gt; 0) {&lt;br /&gt;793                 /* Whee! Actually deliver the signal.  */&lt;br /&gt;794                 if (handle_signal(signr, &amp;info, &amp;ka, oldset, regs) == 0) {&lt;br /&gt;795                         /*&lt;br /&gt;796                          * A signal was successfully delivered; the saved&lt;br /&gt;797                          * sigmask will have been stored in the signal frame,&lt;br /&gt;798                          * and will be restored by sigreturn, so we can simply&lt;br /&gt;799                          * clear the TS_RESTORE_SIGMASK flag.&lt;br /&gt;800                          */&lt;br /&gt;801                         current_thread_info()-&amp;gt;status &amp;= ~TS_RESTORE_SIGMASK;&lt;br /&gt;802                 }&lt;br /&gt;803                 return;&lt;br /&gt;804         }&lt;br /&gt;805 &lt;br /&gt;806         /* Did we come from a system call? */&lt;br /&gt;807         if (syscall_get_nr(current, regs) &amp;gt;= 0) {&lt;br /&gt;808                 /* Restart the system call - no handlers present */&lt;br /&gt;809                 switch (syscall_get_error(current, regs)) {&lt;br /&gt;810                 case -ERESTARTNOHAND:&lt;br /&gt;811                 case -ERESTARTSYS:&lt;br /&gt;812                 case -ERESTARTNOINTR:&lt;br /&gt;813                         regs-&amp;gt;ax = regs-&amp;gt;orig_ax;&lt;br /&gt;814                         regs-&amp;gt;ip -= 2;&lt;br /&gt;815                         break;&lt;br /&gt;816 &lt;br /&gt;817                 case -ERESTART_RESTARTBLOCK:&lt;br /&gt;818                         regs-&amp;gt;ax = NR_restart_syscall;&lt;br /&gt;819                         regs-&amp;gt;ip -= 2;&lt;br /&gt;820                         break;&lt;br /&gt;821                 }&lt;br /&gt;822         }&lt;br /&gt;823 &lt;br /&gt;824         /*&lt;br /&gt;825          * If there's no signal to deliver, we just put the saved sigmask&lt;br /&gt;826          * back.&lt;br /&gt;827          */&lt;br /&gt;828         if (current_thread_info()-&amp;gt;status &amp; TS_RESTORE_SIGMASK) {&lt;br /&gt;829                 current_thread_info()-&amp;gt;status &amp;= ~TS_RESTORE_SIGMASK;&lt;br /&gt;830                 sigprocmask(SIG_SETMASK, &amp;current-&amp;gt;saved_sigmask, NULL);&lt;br /&gt;831         }&lt;br /&gt;832 }&lt;br /&gt;&lt;br /&gt;get_signal_to_deliver() 从进程的信号队列中取得未被屏蔽的信号，能处理的就处理。&lt;br /&gt;剩下的比如用户自己定义了signal_handler()，就要由handle_signal()处理。&lt;br /&gt;&lt;br /&gt;do_signal() -&amp;gt; get_signal_to_deliver()&lt;br /&gt;&lt;br /&gt;1807 int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,&lt;br /&gt;1808                           struct pt_regs *regs, void *cookie)&lt;br /&gt;1809 {&lt;br /&gt;1810         struct sighand_struct *sighand = current-&amp;gt;sighand;&lt;br /&gt;1811         struct signal_struct *signal = current-&amp;gt;signal;&lt;br /&gt;1812         int signr;&lt;br /&gt;1813 &lt;br /&gt;1814 relock:&lt;br /&gt;1815         /*&lt;br /&gt;1816          * We'll jump back here after any time we were stopped in TASK_STOPPED.&lt;br /&gt;1817          * While in TASK_STOPPED, we were considered "frozen enough".&lt;br /&gt;1818          * Now that we woke up, it's crucial if we're supposed to be&lt;br /&gt;1819          * frozen that we freeze now before running anything substantial.&lt;br /&gt;1820          */&lt;br /&gt;1821         try_to_freeze();&lt;br /&gt;1822 &lt;br /&gt;1823         spin_lock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1824         /*&lt;br /&gt;1825          * Every stopped thread goes here after wakeup. Check to see if&lt;br /&gt;1826          * we should notify the parent, prepare_signal(SIGCONT) encodes&lt;br /&gt;1827          * the CLD_ si_code into SIGNAL_CLD_MASK bits.&lt;br /&gt;1828          */&lt;br /&gt;1829         if (unlikely(signal-&amp;gt;flags &amp; SIGNAL_CLD_MASK)) {&lt;br /&gt;1830                 int why = (signal-&amp;gt;flags &amp; SIGNAL_STOP_CONTINUED)&lt;br /&gt;1831                                 ? CLD_CONTINUED : CLD_STOPPED;&lt;br /&gt;1832                 signal-&amp;gt;flags &amp;= ~SIGNAL_CLD_MASK;&lt;br /&gt;1833 &lt;br /&gt;1834                 why = tracehook_notify_jctl(why, CLD_CONTINUED);&lt;br /&gt;1835                 spin_unlock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1836 &lt;br /&gt;1837                 if (why) {&lt;br /&gt;1838                         read_lock(&amp;tasklist_lock);&lt;br /&gt;1839                         do_notify_parent_cldstop(current-&amp;gt;group_leader, why);&lt;br /&gt;1840                         read_unlock(&amp;tasklist_lock);&lt;br /&gt;1841                 }&lt;br /&gt;1842                 goto relock;&lt;br /&gt;1843         }&lt;br /&gt;1844 &lt;br /&gt;1845         for (;;) {&lt;br /&gt;1846                 struct k_sigaction *ka;&lt;br /&gt;1847                 /*&lt;br /&gt;1848                  * Tracing can induce an artifical signal and choose sigaction.&lt;br /&gt;1849                  * The return value in @signr determines the default action,&lt;br /&gt;1850                  * but @info-&amp;gt;si_signo is the signal number we will report.&lt;br /&gt;1851                  */&lt;br /&gt;1852                 signr = tracehook_get_signal(current, regs, info, return_ka);&lt;br /&gt;1853                 if (unlikely(signr &amp;lt; 0))&lt;br /&gt;1854                         goto relock;&lt;br /&gt;1855                 if (unlikely(signr != 0))&lt;br /&gt;1856                         ka = return_ka;&lt;br /&gt;1857                 else {&lt;br /&gt;1858                         if (unlikely(signal-&amp;gt;group_stop_count &amp;gt; 0) &amp;&amp;&lt;br /&gt;1859                             do_signal_stop(0))&lt;br /&gt;1860                                 goto relock;&lt;br /&gt;1861 &lt;br /&gt;1862                         signr = dequeue_signal(current, &amp;current-&amp;gt;blocked,&lt;br /&gt;1863                                                info);&lt;br /&gt;1864 &lt;br /&gt;1865                         if (!signr)&lt;br /&gt;1866                                 break; /* will return 0 */&lt;br /&gt;1867 &lt;br /&gt;1868                         if (signr != SIGKILL) {&lt;br /&gt;1869                                 signr = ptrace_signal(signr, info,&lt;br /&gt;1870                                                       regs, cookie);&lt;br /&gt;1871                                 if (!signr)&lt;br /&gt;1872                                         continue;&lt;br /&gt;1873                         }&lt;br /&gt;1874 &lt;br /&gt;1875                         ka = &amp;sighand-&amp;gt;action[signr-1];&lt;br /&gt;1876                 }&lt;br /&gt;1877 &lt;br /&gt;1878                 /* Trace actually delivered signals. */&lt;br /&gt;1879                 trace_signal_deliver(signr, info, ka);&lt;br /&gt;1880 &lt;br /&gt;1881                 if (ka-&amp;gt;sa.sa_handler == SIG_IGN) /* Do nothing.  */&lt;br /&gt;1882                         continue;&lt;br /&gt;1883                 if (ka-&amp;gt;sa.sa_handler != SIG_DFL) {&lt;br /&gt;1884                         /* Run the handler.  */&lt;br /&gt;1885                         *return_ka = *ka;&lt;br /&gt;1886 &lt;br /&gt;1887                         if (ka-&amp;gt;sa.sa_flags &amp; SA_ONESHOT)&lt;br /&gt;1888                                 ka-&amp;gt;sa.sa_handler = SIG_DFL;&lt;br /&gt;1889 &lt;br /&gt;1890                         break; /* will return non-zero "signr" value */&lt;br /&gt;1891                 }&lt;br /&gt;1892 &lt;br /&gt;1893                 /*&lt;br /&gt;1894                  * Now we are doing the default action for this signal.&lt;br /&gt;1895                  */&lt;br /&gt;1896                 if (sig_kernel_ignore(signr)) /* Default is nothing. */&lt;br /&gt;1897                         continue;&lt;br /&gt;1898 &lt;br /&gt;1899                 /*&lt;br /&gt;1900                  * Global init gets no signals it doesn't want.&lt;br /&gt;1901                  * Container-init gets no signals it doesn't want from same&lt;br /&gt;1902                  * container.&lt;br /&gt;1903                  *&lt;br /&gt;1904                  * Note that if global/container-init sees a sig_kernel_only()&lt;br /&gt;1905                  * signal here, the signal must have been generated internally&lt;br /&gt;1906                  * or must have come from an ancestor namespace. In either&lt;br /&gt;1907                  * case, the signal cannot be dropped.&lt;br /&gt;1908                  */&lt;br /&gt;1909                 if (unlikely(signal-&amp;gt;flags &amp; SIGNAL_UNKILLABLE) &amp;&amp;&lt;br /&gt;1910                                 !sig_kernel_only(signr))&lt;br /&gt;1911                         continue;&lt;br /&gt;1912 &lt;br /&gt;1913                 if (sig_kernel_stop(signr)) {&lt;br /&gt;1914                         /*&lt;br /&gt;1915                          * The default action is to stop all threads in&lt;br /&gt;1916                          * the thread group.  The job control signals&lt;br /&gt;1917                          * do nothing in an orphaned pgrp, but SIGSTOP&lt;br /&gt;1918                          * always works.  Note that siglock needs to be&lt;br /&gt;1919                          * dropped during the call to is_orphaned_pgrp()&lt;br /&gt;1920                          * because of lock ordering with tasklist_lock.&lt;br /&gt;1921                          * This allows an intervening SIGCONT to be posted.&lt;br /&gt;1922                          * We need to check for that and bail out if necessary.&lt;br /&gt;1923                          */&lt;br /&gt;1924                         if (signr != SIGSTOP) {&lt;br /&gt;1925                                 spin_unlock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1926 &lt;br /&gt;1927                                 /* signals can be posted during this window */&lt;br /&gt;1928 &lt;br /&gt;1929                                 if (is_current_pgrp_orphaned())&lt;br /&gt;1930                                         goto relock;&lt;br /&gt;1931 &lt;br /&gt;1932                                 spin_lock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1933                         }&lt;br /&gt;1934 &lt;br /&gt;1935                         if (likely(do_signal_stop(info-&amp;gt;si_signo))) {&lt;br /&gt;1936                                 /* It released the siglock.  */&lt;br /&gt;1937                                 goto relock;&lt;br /&gt;1938                         }&lt;br /&gt;1939 &lt;br /&gt;1940                         /*&lt;br /&gt;1941                          * We didn't actually stop, due to a race&lt;br /&gt;1942                          * with SIGCONT or something like that.&lt;br /&gt;1943                          */&lt;br /&gt;1944                         continue;&lt;br /&gt;1945                 }&lt;br /&gt;1946 &lt;br /&gt;1947                 spin_unlock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1948 &lt;br /&gt;1949                 /*&lt;br /&gt;1950                  * Anything else is fatal, maybe with a core dump.&lt;br /&gt;1951                  */&lt;br /&gt;1952                 current-&amp;gt;flags |= PF_SIGNALED;&lt;br /&gt;1953 &lt;br /&gt;1954                 if (sig_kernel_coredump(signr)) {    // its true for SIGBUS&lt;br /&gt;1955                         if (print_fatal_signals)&lt;br /&gt;1956                                 print_fatal_signal(regs, info-&amp;gt;si_signo);&lt;br /&gt;1957                         /*&lt;br /&gt;1958                          * If it was able to dump core, this kills all&lt;br /&gt;1959                          * other threads in the group and synchronizes with&lt;br /&gt;1960                          * their demise.  If we lost the race with another&lt;br /&gt;1961                          * thread getting here, it set group_exit_code&lt;br /&gt;1962                          * first and our do_group_exit call below will use&lt;br /&gt;1963                          * that value and ignore the one we pass it.&lt;br /&gt;1964                          */&lt;br /&gt;1965                         do_coredump(info-&amp;gt;si_signo, info-&amp;gt;si_signo, regs);&lt;br /&gt;1966                 }&lt;br /&gt;1967 &lt;br /&gt;1968                 /*&lt;br /&gt;1969                  * Death signals, no core dump.&lt;br /&gt;1970                  */&lt;br /&gt;1971                 do_group_exit(info-&amp;gt;si_signo);&lt;br /&gt;1972                 /* NOTREACHED */&lt;br /&gt;1973         }&lt;br /&gt;1974         spin_unlock_irq(&amp;sighand-&amp;gt;siglock);&lt;br /&gt;1975         return signr;&lt;br /&gt;1976 }&lt;br /&gt;&lt;br /&gt;dequeue_signal()每次提取一个未被屏蔽的信号sig，从struct queue取得info，释放对应sig的sigqueue。&lt;br /&gt;取得 struct sigaction:&lt;br /&gt;1875                         ka = &amp;sighand-&amp;gt;action[signr-1];&lt;br /&gt;&lt;br /&gt;然后根据信号的disposition: SIG_IGN !SIG_DFL SIGDFL 来处理。 man 7 signal&lt;br /&gt;&lt;br /&gt;Signal Dispositions&lt;br /&gt;&lt;br /&gt;       Term   Default action is to terminate the process.&lt;br /&gt;       Ign    Default action is to ignore the signal.&lt;br /&gt;       Core   Default action is to terminate the process and dump core (see core(5)).&lt;br /&gt;       Stop   Default action is to stop the process.&lt;br /&gt;       Cont   Default action is to continue the process if it is currently stopped.&lt;br /&gt;&lt;br /&gt;#define sig_kernel_only(sig) \&lt;br /&gt;        (((sig) &amp;lt; SIGRTMIN) &amp;&amp; siginmask(sig, SIG_KERNEL_ONLY_MASK))&lt;br /&gt;#define sig_kernel_coredump(sig) \&lt;br /&gt;        (((sig) &amp;lt; SIGRTMIN) &amp;&amp; siginmask(sig, SIG_KERNEL_COREDUMP_MASK))&lt;br /&gt;#define sig_kernel_ignore(sig) \&lt;br /&gt;        (((sig) &amp;lt; SIGRTMIN) &amp;&amp; siginmask(sig, SIG_KERNEL_IGNORE_MASK))&lt;br /&gt;#define sig_kernel_stop(sig) \&lt;br /&gt;        (((sig) &amp;lt; SIGRTMIN) &amp;&amp; siginmask(sig, SIG_KERNEL_STOP_MASK))&lt;br /&gt;&lt;br /&gt;#define sig_user_defined(t, signr) \&lt;br /&gt;        (((t)-&amp;gt;sighand-&amp;gt;action[(signr)-1].sa.sa_handler != SIG_DFL) &amp;&amp;  \&lt;br /&gt;         ((t)-&amp;gt;sighand-&amp;gt;action[(signr)-1].sa.sa_handler != SIG_IGN))&lt;br /&gt;&lt;br /&gt;#define sig_fatal(t, signr) \&lt;br /&gt;        (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) &amp;&amp; \&lt;br /&gt;         (t)-&amp;gt;sighand-&amp;gt;action[(signr)-1].sa.sa_handler == SIG_DFL)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#define SIG_KERNEL_ONLY_MASK (\&lt;br /&gt;        rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))&lt;br /&gt;&lt;br /&gt;#define SIG_KERNEL_STOP_MASK (\&lt;br /&gt;        rt_sigmask(SIGSTOP)   |  rt_sigmask(SIGTSTP)   | \&lt;br /&gt;        rt_sigmask(SIGTTIN)   |  rt_sigmask(SIGTTOU)   )&lt;br /&gt;&lt;br /&gt;#define SIG_KERNEL_COREDUMP_MASK (\&lt;br /&gt;        rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \&lt;br /&gt;        rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \&lt;br /&gt;        rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \&lt;br /&gt;        rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \&lt;br /&gt;        rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \&lt;br /&gt;        SIGEMT_MASK                                    )&lt;br /&gt;&lt;br /&gt;#define SIG_KERNEL_IGNORE_MASK (\&lt;br /&gt;        rt_sigmask(SIGCONT)   |  rt_sigmask(SIGCHLD)   | \&lt;br /&gt;        rt_sigmask(SIGWINCH)  |  rt_sigmask(SIGURG)    )&lt;br /&gt;&lt;br /&gt;如果用户程序中没有对 SIGCHLD 设置sig_handler()，则SIGCHLD属于sig_kernel_ignore类型，SIG_IGN。&lt;br /&gt;而处理 SIGKILL 时将执行 1971                 do_group_exit(info-&amp;gt;si_signo);&lt;br /&gt;&lt;br /&gt;do_group_exit()最后调用do_exit()结束自己的生命，对SIGKILL的处理就结束了，符合man 7 signal。&lt;br /&gt;&lt;br /&gt;而对于 SIGBUS SIGSEGV 等 sig_kernel_coredump() 类型，就要do_coredump()生成core文件了。&lt;br /&gt;&lt;br /&gt;dequeue_signal() -&amp;gt; __dequeue_signal()&lt;br /&gt;&lt;br /&gt;static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, siginfo_t *info)&lt;br /&gt;{&lt;br /&gt;        int sig = next_signal(pending, mask);  // Given the mask, find the first available signal&lt;br /&gt;&lt;br /&gt;        if (sig) {&lt;br /&gt;                if (current-&amp;gt;notifier) {&lt;br /&gt;                        if (sigismember(current-&amp;gt;notifier_mask, sig)) {&lt;br /&gt;                                if (!(current-&amp;gt;notifier)(current-&amp;gt;notifier_data)) {&lt;br /&gt;                                        clear_thread_flag(TIF_SIGPENDING);&lt;br /&gt;                                        return 0;&lt;br /&gt;                                }    &lt;br /&gt;                        }    &lt;br /&gt;                }    &lt;br /&gt;&lt;br /&gt;                collect_signal(sig, pending, info);&lt;br /&gt;        }    &lt;br /&gt;&lt;br /&gt;        return sig; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;dequeue_signal() -&amp;gt; __dequeue_signal() -&amp;gt; collect_signal()&lt;br /&gt;&lt;br /&gt;static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)&lt;br /&gt;{&lt;br /&gt;        struct sigqueue *q, *first = NULL;&lt;br /&gt;&lt;br /&gt;        /*&lt;br /&gt;         * Collect the siginfo appropriate to this signal.  Check if&lt;br /&gt;         * there is another siginfo for the same signal.&lt;br /&gt;        */&lt;br /&gt;        list_for_each_entry(q, &amp;list-&amp;gt;list, list) {&lt;br /&gt;                if (q-&amp;gt;info.si_signo == sig) {&lt;br /&gt;                        if (first)&lt;br /&gt;                                goto still_pending;&lt;br /&gt;                        first = q;&lt;br /&gt;                }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        sigdelset(&amp;list-&amp;gt;signal, sig);&lt;br /&gt;&lt;br /&gt;        if (first) {&lt;br /&gt;still_pending:&lt;br /&gt;                list_del_init(&amp;first-&amp;gt;list);&lt;br /&gt;                copy_siginfo(info, &amp;first-&amp;gt;info);&lt;br /&gt;                __sigqueue_free(first);&lt;br /&gt;        } else {&lt;br /&gt;                /* Ok, it wasn't in the queue.  This must be&lt;br /&gt;                   a fast-pathed signal or we must have been&lt;br /&gt;                   out of queue space.  So zero out the info.&lt;br /&gt;                 */&lt;br /&gt;                info-&amp;gt;si_signo = sig;&lt;br /&gt;                info-&amp;gt;si_errno = 0;&lt;br /&gt;                info-&amp;gt;si_code = SI_USER;&lt;br /&gt;                info-&amp;gt;si_pid = 0;&lt;br /&gt;                info-&amp;gt;si_uid = 0;&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;handle_signal()设置各类context：调用put_user()把kernel stack中的内容保存到user stack中，然后修&lt;br /&gt;改某些kernel stack中的register值，为用户态sig_handler()的运行做准备。这里就不看细节了。&lt;br /&gt;&lt;br /&gt;handle_signal() -&amp;gt; setup_rt_frame() -&amp;gt; ia32_setup_frame()&lt;br /&gt;&lt;br /&gt;int ia32_setup_frame(int sig, struct k_sigaction *ka, compat_sigset_t *set, struct pt_regs *regs)&lt;br /&gt;{               &lt;br /&gt;        struct sigframe_ia32 __user *frame;&lt;br /&gt;        void __user *restorer; &lt;br /&gt;        int err = 0;&lt;br /&gt;        void __user *fpstate = NULL;&lt;br /&gt;&lt;br /&gt;        /* copy_to_user optimizes that into a single 8 byte store */&lt;br /&gt;        static const struct {&lt;br /&gt;                u16 poplmovl; &lt;br /&gt;                u32 val;&lt;br /&gt;                u16 int80;&lt;br /&gt;        } __attribute__((packed)) code = {&lt;br /&gt;                0xb858,          /* popl %eax ; movl $...,%eax */&lt;br /&gt;                __NR_ia32_sigreturn,&lt;br /&gt;                0x80cd,         /* int $0x80 */&lt;br /&gt;        };      &lt;br /&gt;                        &lt;br /&gt;        frame = get_sigframe(ka, regs, sizeof(*frame), &amp;fpstate);  // determine user sp&lt;br /&gt;                        &lt;br /&gt;        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))&lt;br /&gt;                return -EFAULT;&lt;br /&gt;&lt;br /&gt;        if (__put_user(sig, &amp;frame-&amp;gt;sig))&lt;br /&gt;                return -EFAULT;&lt;br /&gt;                &lt;br /&gt;        if (ia32_setup_sigcontext(&amp;frame-&amp;gt;sc, fpstate, regs, set-&amp;gt;sig[0]))  // here&lt;br /&gt;                return -EFAULT;&lt;br /&gt;&lt;br /&gt;        if (_COMPAT_NSIG_WORDS &amp;gt; 1) {&lt;br /&gt;                if (__copy_to_user(frame-&amp;gt;extramask, &amp;set-&amp;gt;sig[1], sizeof(frame-&amp;gt;extramask)))&lt;br /&gt;                        return -EFAULT;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (ka-&amp;gt;sa.sa_flags &amp; SA_RESTORER) {&lt;br /&gt;                restorer = ka-&amp;gt;sa.sa_restorer;&lt;br /&gt;                restorer = ka-&amp;gt;sa.sa_restorer;&lt;br /&gt;        } else {&lt;br /&gt;                /* Return stub is in 32bit vsyscall page */&lt;br /&gt;                if (current-&amp;gt;mm-&amp;gt;context.vdso)&lt;br /&gt;                        restorer = VDSO32_SYMBOL(current-&amp;gt;mm-&amp;gt;context.vdso, sigreturn);&lt;br /&gt;                else&lt;br /&gt;                        restorer = &amp;frame-&amp;gt;retcode;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        put_user_try {&lt;br /&gt;                put_user_ex(ptr_to_compat(restorer), &amp;frame-&amp;gt;pretcode);&lt;br /&gt;&lt;br /&gt;                /*&lt;br /&gt;                 * These are actually not used anymore, but left because some&lt;br /&gt;                 * gdb versions depend on them as a marker.&lt;br /&gt;                 */&lt;br /&gt;                put_user_ex(*((u64 *)&amp;code), (u64 *)frame-&amp;gt;retcode);&lt;br /&gt;        } put_user_catch(err);&lt;br /&gt;&lt;br /&gt;        if (err)&lt;br /&gt;                return -EFAULT;&lt;br /&gt;&lt;br /&gt;        /* Set up registers for signal handler */&lt;br /&gt;        regs-&amp;gt;sp = (unsigned long) frame;&lt;br /&gt;        regs-&amp;gt;ip = (unsigned long) ka-&amp;gt;sa.sa_handler;&lt;br /&gt;&lt;br /&gt;        /* Make -mregparm=3 work */&lt;br /&gt;        regs-&amp;gt;ax = sig;&lt;br /&gt;        regs-&amp;gt;dx = 0;&lt;br /&gt;        regs-&amp;gt;cx = 0;&lt;br /&gt;&lt;br /&gt;        loadsegment(ds, __USER32_DS);&lt;br /&gt;        loadsegment(es, __USER32_DS);&lt;br /&gt;&lt;br /&gt;        regs-&amp;gt;cs = __USER32_CS;&lt;br /&gt;        regs-&amp;gt;ss = __USER32_DS;&lt;br /&gt;&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;handle_signal()之后就层层返回到汇编代码: &lt;br /&gt; 678         call do_notify_resume&lt;br /&gt; 679         jmp resume_userspace_sig&lt;br /&gt;&lt;br /&gt;define resume_userspace_sig    check_userspace&lt;br /&gt;&lt;br /&gt;在check_userspace内会执行jmp restore_all将进程的kernel stack内容恢复到各个register中，从而开始&lt;br /&gt;在用户态执行用户自定义的sig_handler()，&lt;br /&gt;&lt;br /&gt;执行完sig_handler()之后再调用sigreturn进入kernel mode。sigreturn先做一些设置，然后执行&lt;br /&gt;restore_sigcontext() 用get_user()恢复kernel stack。最后返回到user mode继续执行用户程序。&lt;br /&gt;sys_sigreturn()对应sigreturn，这里不看了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;二。SI_KERNEL 表示kernel发信号，使用的是 force_sig() 系列。&lt;br /&gt;&lt;br /&gt;比如do_page_fault()中，handle_mm_fault()返回后会检查，如果发现 VM_FAULT_ERROR 就要处理错误了。&lt;br /&gt;处理错误的过程中kernel就可能会发信号。&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * This routine handles page faults.  It determines the address,&lt;br /&gt; * and the problem, and then passes it off to one of the appropriate&lt;br /&gt; * routines.&lt;br /&gt; */&lt;br /&gt;dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)&lt;br /&gt;{&lt;br /&gt;             ....&lt;br /&gt;        fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);&lt;br /&gt;&lt;br /&gt;        if (unlikely(fault &amp; VM_FAULT_ERROR)) {&lt;br /&gt;                mm_fault_error(regs, error_code, address, fault);&lt;br /&gt;                return;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (fault &amp; VM_FAULT_MAJOR) {&lt;br /&gt;                tsk-&amp;gt;maj_flt++;&lt;br /&gt;                perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, regs, address);&lt;br /&gt;        } else {&lt;br /&gt;                tsk-&amp;gt;min_flt++;&lt;br /&gt;                perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, regs, address);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        check_v8086_mode(regs, address, tsk);&lt;br /&gt;&lt;br /&gt;        up_read(&amp;mm-&amp;gt;mmap_sem);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;do_page_fault() -&amp;gt; mm_fault_error()&lt;br /&gt;&lt;br /&gt;static noinline void mm_fault_error(struct pt_regs *regs, unsigned long error_code,&lt;br /&gt;                                    unsigned long address, unsigned int fault)&lt;br /&gt;{&lt;br /&gt;        if (fault &amp; VM_FAULT_OOM) {&lt;br /&gt;                out_of_memory(regs, error_code, address);            // call OOM killer&lt;br /&gt;        } else {&lt;br /&gt;                if (fault &amp; (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON))&lt;br /&gt;                        do_sigbus(regs, error_code, address, fault);&lt;br /&gt;                else&lt;br /&gt;                        BUG();&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;这里用上了 OOM Killer。 &lt;br /&gt;当系统实在没有内存可用时，会调用 OOM Killer 杀掉一个进程，希望之后能有空余内存。比如用户程序用&lt;br /&gt;malloc()申请了很多内存，malloc()通过mmap()给进程分配了vma等虚拟存储结构，并不分配物理内存。即使&lt;br /&gt;此时物理内存已经很少，并不能满足申请。这样当程序运行期间通过page fault获取物理内存时，无物理内&lt;br /&gt;存可用，就会试图调用 OOM Killer 杀死一个进程。kernel发 SIGKILL 信号，通过force_sig(SIGKILL, p);&lt;br /&gt;实现。但 OOM Killer 几乎没用：由于kernel thread 没有用户空间，也就没有返回到用户态的机会，所以&lt;br /&gt;不选择杀kernel thread，要杀用户进程。而如果被选择的进程运行于user mode，则必须等它以某种方式进 &lt;br /&gt;入kernel mode，然后返回到user mode时，才能处理SIGKILL，被杀掉，不具实时性。 &lt;br /&gt;&lt;br /&gt;因此在用户态用 kill -9 杀kernel thread是没用的。&lt;br /&gt;$ ps aux |less      带[]的是kernel thread&lt;br /&gt;&lt;br /&gt;USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMand&lt;br /&gt;USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND&lt;br /&gt;root         1  0.0  0.0   2028   580 ?        Ss   Apr22   0:00 /sbin/init&lt;br /&gt;root         2  0.0  0.0      0     0 ?        S&amp;lt;   Apr22   0:00 [kthreadd]&lt;br /&gt;...&lt;br /&gt;root       806  0.0  0.1  35680  1084 ?        Sl   Apr22   0:00 /sbin/rsyslogd -c 4&lt;br /&gt;....&lt;br /&gt;root     13168  0.0  0.0      0     0 ?        S    12:34   0:00 [pdflush]&lt;br /&gt;root     13169  0.0  0.0      0     0 ?        S    12:35   0:00 [pdflush]&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;kthreadd 和 pdflush 都是kernel thread，而 rsyslogd 和 klogd 不是，虽然它们四个都是daemon。&lt;br /&gt;&lt;br /&gt;继续看另一种情况 do_sigbus()&lt;br /&gt;&lt;br /&gt;static void do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,&lt;br /&gt;                      unsigned int fault)&lt;br /&gt;{&lt;br /&gt;        struct task_struct *tsk = current;&lt;br /&gt;        struct mm_struct *mm = tsk-&amp;gt;mm;&lt;br /&gt;        int code = BUS_ADRERR;&lt;br /&gt;&lt;br /&gt;        up_read(&amp;mm-&amp;gt;mmap_sem);&lt;br /&gt;&lt;br /&gt;        /* Kernel mode? Handle exceptions or die: */&lt;br /&gt;        if (!(error_code &amp; PF_USER))&lt;br /&gt;                no_context(regs, error_code, address);   // fixup_exception()&lt;br /&gt;&lt;br /&gt;        /* User-space =&amp;gt; ok to do another page fault: */&lt;br /&gt;        if (is_prefetch(regs, error_code, address))&lt;br /&gt;                return;&lt;br /&gt;&lt;br /&gt;        tsk-&amp;gt;thread.cr2         = address;&lt;br /&gt;        tsk-&amp;gt;thread.error_code  = error_code;&lt;br /&gt;        tsk-&amp;gt;thread.trap_no     = 14;&lt;br /&gt;&lt;br /&gt;#ifdef CONFIG_MEMORY_FAILURE&lt;br /&gt;        if (fault &amp; VM_FAULT_HWPOISON) {&lt;br /&gt;                printk(KERN_ERR&lt;br /&gt;        "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",&lt;br /&gt;                        tsk-&amp;gt;comm, tsk-&amp;gt;pid, address);&lt;br /&gt;                code = BUS_MCEERR_AR;&lt;br /&gt;        }&lt;br /&gt;#endif&lt;br /&gt;        force_sig_info_fault(SIGBUS, code, address, tsk);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Page fault error code bits:&lt;br /&gt; *&lt;br /&gt; *   bit 0 ==    0: no page found       1: protection fault&lt;br /&gt; *   bit 1 ==    0: read access         1: write access&lt;br /&gt; *   bit 2 ==    0: kernel-mode access  1: user-mode access&lt;br /&gt; *   bit 3 ==                           1: use of reserved bit detected&lt;br /&gt; *   bit 4 ==                           1: fault was an instruction fetch&lt;br /&gt; */&lt;br /&gt;enum x86_pf_error_code {&lt;br /&gt;&lt;br /&gt;        PF_PROT         =               1 &amp;lt;&amp;lt; 0,&lt;br /&gt;        PF_WRITE        =               1 &amp;lt;&amp;lt; 1,&lt;br /&gt;        PF_USER         =               1 &amp;lt;&amp;lt; 2,&lt;br /&gt;        PF_RSVD         =               1 &amp;lt;&amp;lt; 3,&lt;br /&gt;        PF_INSTR        =               1 &amp;lt;&amp;lt; 4,&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;kernel fault用fixup_exception查表的方式来处理; user fault 就给current发 SIGBUS 信号。&lt;br /&gt;man 7 signal 知道表示 Bus error (bad memory access)。&lt;br /&gt;Signal Dispositions   Core   Default action is to terminate the process and  dump  core&lt;br /&gt;&lt;br /&gt;接下来force_sig_info_fault()最终也是调用 send_signal()&lt;br /&gt;&lt;br /&gt;static void force_sig_info_fault(int si_signo, int si_code, unsigned long address,&lt;br /&gt;                                 struct task_struct *tsk)&lt;br /&gt;{&lt;br /&gt;        siginfo_t info;&lt;br /&gt;&lt;br /&gt;        info.si_signo   = si_signo;&lt;br /&gt;        info.si_errno   = 0;&lt;br /&gt;        info.si_code    = si_code;&lt;br /&gt;        info.si_addr    = (void __user *)address;&lt;br /&gt;        info.si_addr_lsb = si_code == BUS_MCEERR_AR ? PAGE_SHIFT : 0;&lt;br /&gt;&lt;br /&gt;        force_sig_info(si_signo, &amp;info, tsk);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;1029 /*&lt;br /&gt;1030  * Force a signal that the process can't ignore: if necessary&lt;br /&gt;1031  * we unblock the signal and change any SIG_IGN to SIG_DFL.&lt;br /&gt;1032  *&lt;br /&gt;1033  * Note: If we unblock the signal, we always reset it to SIG_DFL,&lt;br /&gt;1034  * since we do not want to have a signal handler that was blocked&lt;br /&gt;1035  * be invoked when user space had explicitly blocked it.&lt;br /&gt;1036  *&lt;br /&gt;1037  * We don't want to have recursive SIGSEGV's etc, for example,&lt;br /&gt;1038  * that is why we also clear SIGNAL_UNKILLABLE.&lt;br /&gt;1039  */&lt;br /&gt;1040 int&lt;br /&gt;1041 force_sig_info(int sig, struct siginfo *info, struct task_struct *t)&lt;br /&gt;1042 {&lt;br /&gt;1043         unsigned long int flags;&lt;br /&gt;1044         int ret, blocked, ignored;&lt;br /&gt;1045         struct k_sigaction *action;&lt;br /&gt;1046 &lt;br /&gt;1047         spin_lock_irqsave(&amp;t-&amp;gt;sighand-&amp;gt;siglock, flags);&lt;br /&gt;1048         action = &amp;t-&amp;gt;sighand-&amp;gt;action[sig-1];&lt;br /&gt;1049         ignored = action-&amp;gt;sa.sa_handler == SIG_IGN;&lt;br /&gt;1050         blocked = sigismember(&amp;t-&amp;gt;blocked, sig);&lt;br /&gt;1051         if (blocked || ignored) {&lt;br /&gt;1052                 action-&amp;gt;sa.sa_handler = SIG_DFL;&lt;br /&gt;1053                 if (blocked) {&lt;br /&gt;1054                         sigdelset(&amp;t-&amp;gt;blocked, sig);&lt;br /&gt;1055                         recalc_sigpending_and_wake(t);&lt;br /&gt;1056                 }&lt;br /&gt;1057         }&lt;br /&gt;1058         if (action-&amp;gt;sa.sa_handler == SIG_DFL)&lt;br /&gt;1059                 t-&amp;gt;signal-&amp;gt;flags &amp;= ~SIGNAL_UNKILLABLE;&lt;br /&gt;1060         ret = specific_send_sig_info(sig, info, t);&lt;br /&gt;1061         spin_unlock_irqrestore(&amp;t-&amp;gt;sighand-&amp;gt;siglock, flags);&lt;br /&gt;1062 &lt;br /&gt;1063         return ret;&lt;br /&gt;1064 }&lt;br /&gt;&lt;br /&gt;static int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)&lt;br /&gt;{&lt;br /&gt;        return send_signal(sig, info, t, 0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;force_sig()和 send_sig()的区别在于:&lt;br /&gt;&lt;br /&gt;void force_sig(int sig, struct task_struct *p)&lt;br /&gt;{&lt;br /&gt;        force_sig_info(sig, SEND_SIG_PRIV, p);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int send_sig(int sig, struct task_struct *p, int priv)&lt;br /&gt;{&lt;br /&gt;        return send_sig_info(sig, __si_special(priv), p);&lt;br /&gt;}       &lt;br /&gt;&lt;br /&gt;#define __si_special(priv) \&lt;br /&gt;        ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)&lt;br /&gt;&lt;br /&gt;/* These can be the second arg to send_sig_info/send_group_sig_info.  */&lt;br /&gt;#define SEND_SIG_NOINFO ((struct siginfo *) 0)&lt;br /&gt;#define SEND_SIG_PRIV   ((struct siginfo *) 1)&lt;br /&gt;#define SEND_SIG_FORCED ((struct siginfo *) 2)&lt;br /&gt;&lt;br /&gt;在处理SIGBUS时，要进行coredump。而处理 SIGKILL时是不用coredump的，这正符合man 7 signal的说明。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-2533463165560997379?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/2533463165560997379/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/04/signal.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/2533463165560997379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/2533463165560997379'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/04/signal.html' title='signal'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-8141902608297588468</id><published>2010-03-31T19:28:00.044+08:00</published><updated>2011-07-05T10:21:07.073+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>music</title><content type='html'>&lt;pre&gt;&lt;br /&gt;中学时最大愿望就是能有个录音机。大学为了英语过级终于买了，但真正收集整理自己喜欢的歌曲却是30出&lt;br /&gt;头的事。音乐是一个时空利器，一下子就能把我的思绪带回到几十年前，直到记忆所及之处，把许多美好的&lt;br /&gt;时光重新演奏给你，这种另时光倒转的魔力据基督教会的人说是Lucifer的能力体现。音乐也能让我们深思许&lt;br /&gt;多问题，比如 Hand in Hand 这么美妙的歌曲带给世界绝不仅仅是一届经典的汉城奥运会开幕，而是一个正&lt;br /&gt;在崛起的亚洲四小龙。伴有大量police的奥运会岂能带来这样的崛起？&lt;br /&gt;&lt;br /&gt;喜欢的歌手: 崔健。&lt;br /&gt;最喜欢的一首歌: 崔健的 &amp;lt;&amp;lt;一塊紅布&amp;gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;崔健用心去唱，用大脑去歌词，唱歌吹小号，弹吉他。歌中带着淳朴，不假唱，不是戏子，他是一个会思考&lt;br /&gt;的robin man，绝不是一个普通的歌星。看上去似乎他并不红，现实中轻人很少有知道，甚至和我一个年龄段&lt;br /&gt;的人最多知道一首&amp;lt;&amp;lt;一無所有&amp;gt;&amp;gt;，却不知道那只是序言，后面还有更加精彩的，精彩了快30年&lt;br /&gt;了。坚信在我的后半生时间段，演奏和歌词的微妙程度不会有超过这首歌的。&lt;br /&gt;&lt;br /&gt;崔健60一代，有着强烈的社会责任感，面相上就带着倔强。正因为如此，他上不了春晚，也正说明了人品好。&lt;br /&gt;宁可被封杀也要唱，中国就缺这种有血性的，在大是大非面前绝对不能妥协！人过30会放弃之前的很多原则&lt;br /&gt;转而向现实屈服，而崔健50了也没变，太爷们了！&lt;br /&gt;&lt;br /&gt;&amp;lt;&amp;lt;最後一槍&amp;gt;&amp;gt;最初是写给1979年越战士兵的，没想到不久就有了别的更加深刻的寓意，具有我们并不&lt;br /&gt;想看到的戏剧性。最有创意的要数1989年台湾和港版&amp;lt;&amp;lt;一無所有&amp;gt;&amp;gt;那张专辑的封面。&lt;br /&gt;&lt;br /&gt;                                一塊紅布&lt;br /&gt;                           &lt;br /&gt;                                唱：崔健&lt;br /&gt;                           &lt;br /&gt;                           那天是你用一块红布&lt;br /&gt;                           蒙住我双眼也蒙住了天&lt;br /&gt;                           你觉问我看见了什么&lt;br /&gt;                           我说我看见了幸福&lt;br /&gt;                           这个感觉真让我舒服&lt;br /&gt;                           它让我忘掉我没地儿住&lt;br /&gt;                           你问我还要去何方&lt;br /&gt;                           我说要上你的路&lt;br /&gt;                           &lt;br /&gt;                           看不见你也看不见路&lt;br /&gt;                           我的手也被你攥住&lt;br /&gt;                           你问我还在想什么&lt;br /&gt;                           我说我要让你做主&lt;br /&gt;                           我感觉你不是铁&lt;br /&gt;                           却象铁一样强和烈&lt;br /&gt;                           我感觉你身上有血&lt;br /&gt;                           因为你的手是热呼呼&lt;br /&gt;                           &lt;br /&gt;                           我感觉这不是荒野&lt;br /&gt;                           却看不见这地已经干裂&lt;br /&gt;                           我感觉我要喝点水&lt;br /&gt;                           可你的嘴将我的嘴堵住&lt;br /&gt;                           我不能走我也不能哭&lt;br /&gt;                           因为我的身体已经干枯&lt;br /&gt;                           我要永远这样陪伴着你&lt;br /&gt;                           因为我最知道你的痛苦&lt;br /&gt;                           嘟~嘟~~嘟~~~&lt;br /&gt;                           ...&lt;br /&gt;&lt;br /&gt;最喜欢看的一段摇滚视频是崔健唐朝眼镜蛇1993年在柏林的"中国摇滚在柏林"。开篇就是撒点野和假行僧。&lt;br /&gt;现场弹奏古筝的是一个女孩，叫张珊。那古筝弹的真好听，特别是那一举一动太迷人了，第一次看就被她吸&lt;br /&gt;引住了，现在是中央民族大学音乐系教师，68年的。一直就想娶个女教师或者会弹琴的，和同龄人以及80后&lt;br /&gt;的很少有共同语言，不知道以后是否能找到一位。喜欢和比我大10岁的那批大学生交谈，他们不是书呆子，&lt;br /&gt;很小就了解了这个社会。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;喜欢西北风。自从88年春晚程琳一首&amp;lt;&amp;lt;信天游&amp;gt;&amp;gt;之后，西北风刮起来了。&lt;br /&gt;&lt;br /&gt;西北风歌曲的歌词都有浓郁的生活味道，反映的是真实纯朴的生活，折射出来的是当时相对轻松的政治氛围，&lt;br /&gt;当时得势的是真正的改革派，有魄力也宽容，能容忍不同声音的表达。文艺界百家争鸣，相声，小品，歌曲&lt;br /&gt;都体现出来: "领导，冒号！"，&amp;lt;&amp;lt;英雄母亲的一天&amp;gt;&amp;gt;，西北风是各自的代表。&lt;br /&gt;&lt;br /&gt;人事大换血后，这些附属物也全部被咔嚓掉了，春晚被声色犬马全面垄断，离人们生活越来越远。最恶心的&lt;br /&gt;是还弄出一种论调说什么西北风艺术价值不大。西北风是对生活的反思，进而促进决策层政策的制定，岂止&lt;br /&gt;是歌曲? 弄出这种论调无非就是想让人赶快忘掉那段历史，他们很怕。&lt;br /&gt;&lt;br /&gt;崔健的歌是呐喊，隐晦而微妙，却没给我们解决办法，有鲁迅的风格。而仔细品味西北风，犹如胡适般务实，&lt;br /&gt;踏踏实实革新是正道。韦唯的&amp;lt;&amp;lt;心愿&amp;gt;&amp;gt;，一听那歌词，立刻触动了我的神经，这歌词近百年的历&lt;br /&gt;史，诉说出痛苦的过去，革新的艰难，立志通过自身的奉献来创造中华的崛起，20多年过去了，从歌词还可&lt;br /&gt;以看出那股激情和决心，听过之后会让人心潮澎湃。&lt;br /&gt;&lt;br /&gt;西北风歌曲最典型的代表就是: &amp;lt;&amp;lt;信天游&amp;gt;&amp;gt;，&amp;lt;&amp;lt;黄土高坡&amp;gt;&amp;gt;，&amp;lt;&amp;lt;我热恋的故乡&amp;gt;&amp;gt;&lt;br /&gt;最喜欢的代表人物: 范琳琳，胡月&lt;br /&gt;&lt;br /&gt;                              我热恋的故乡&lt;br /&gt;                           &lt;br /&gt;                           词：广征 曲：徐沛东&lt;br /&gt;                           &lt;br /&gt;                             演唱：胡月&lt;br /&gt;                           &lt;br /&gt;                                 故乡&lt;br /&gt;                                 故乡&lt;br /&gt;                           我的故乡并不美&lt;br /&gt;                           低矮的草房苦涩的井水&lt;br /&gt;                           一条时常干涸的小河&lt;br /&gt;                           依恋在小村周围&lt;br /&gt;                           一片贫瘠的土地上&lt;br /&gt;                           收获着微薄的希望&lt;br /&gt;                           住了一年又一年&lt;br /&gt;                           生活了一辈又一辈&lt;br /&gt;                           &lt;br /&gt;                           &lt;br /&gt;                           忙不完的黄土地&lt;br /&gt;                           喝不干的苦井水&lt;br /&gt;                           男人为你累弯了腰&lt;br /&gt;                           女人也要为你锁愁眉&lt;br /&gt;                           离不了的矮草房&lt;br /&gt;                           养活了人的苦井水&lt;br /&gt;                           住了一年又一年&lt;br /&gt;                           生活了一辈又一辈&lt;br /&gt;                           &lt;br /&gt;                           &lt;br /&gt;                           哦...哦...&lt;br /&gt;                           故乡，故乡&lt;br /&gt;                           亲不够的故乡土&lt;br /&gt;                           恋不够的家乡水&lt;br /&gt;                           我要用真情和汗水&lt;br /&gt;                           把你变成地也肥呀水也美呀&lt;br /&gt;                           地也肥呀水也美呀&lt;br /&gt;                           地肥水肥水美&lt;br /&gt;&lt;br /&gt;歌词开头就说了我的故乡不美，接下来“低矮的草房苦涩的井水” “微薄的希望”，就这些字眼，放到今天这么&lt;br /&gt;不河蟹你别想唱。&lt;br /&gt;&lt;br /&gt;    list如下，每首都是我精心挑选的，可谓用心良苦。其中86版西游记原声是192K的带。音乐书画都通神&lt;br /&gt;的，静心听喜欢的歌曲确实有魂离体外的感觉。歌词好的都集中80后期和90前期。喜欢的女歌手: 王菲、&lt;br /&gt;邓丽君、范琳琳、毛阿敏。&lt;br /&gt;&lt;br /&gt;经典合唱：&lt;br /&gt;&lt;br /&gt;群星 - 明天会更好.mp3&lt;br /&gt;群星 - 让世界充满爱.mp3&lt;br /&gt;群星 - 今又龙年.mp3&lt;br /&gt;群星 - 历史的伤口.mp3&lt;br /&gt;群星 - 奥林匹克风.mp3&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ch:&lt;br /&gt;2046.Connie Francis - Siboney .ape&lt;br /&gt;2046.Georges Delerue - Julien Et Barbara (Instrumental).ape&lt;br /&gt;2046.Nat King Cole - The Chrismas Song.ape&lt;br /&gt;2046.Secret Garden - Adagio (Instrumental, Featuring David Agnew).ape&lt;br /&gt;2046.梅林茂 - Main Theme .ape&lt;br /&gt;2046.梅林茂 - Polonaise (Instrumental) .ape&lt;br /&gt;Beyond - 不再犹豫.ape&lt;br /&gt;Beyond - 光辉岁月.ape&lt;br /&gt;Beyond - 再见理想.ape&lt;br /&gt;Beyond - 农民.ape&lt;br /&gt;Beyond - 冷雨夜.ape&lt;br /&gt;Beyond - 午夜怨曲.ape&lt;br /&gt;Beyond - 可否冲破.ape&lt;br /&gt;Beyond - 喜欢你.ape&lt;br /&gt;Beyond - 大地.ape&lt;br /&gt;Beyond - 怀念你.ape&lt;br /&gt;Beyond - 情人.ape&lt;br /&gt;Beyond - 愿我能.ape&lt;br /&gt;Beyond - 报答一生.ape&lt;br /&gt;Beyond - 无尽空虚.ape&lt;br /&gt;Beyond - 海阔天空.ape&lt;br /&gt;Beyond - 灰色轨迹.ape&lt;br /&gt;Beyond - 真的爱你.ape&lt;br /&gt;Beyond - 长城.ape&lt;br /&gt;Jean - 下雪天.mp3&lt;br /&gt;Jean - 不必太在意.mp3&lt;br /&gt;Jean - 与爱有染.mp3&lt;br /&gt;Jean - 光芒.mp3&lt;br /&gt;Jean - 再回首.mp3&lt;br /&gt;Jean - 别让爱情走了样.mp3&lt;br /&gt;Jean - 女人花-琴2.mp3&lt;br /&gt;Jean - 想把我唱给你听.mp3&lt;br /&gt;Jean - 活色生香.mp3&lt;br /&gt;Jean - 淡淡的歌.mp3&lt;br /&gt;Jean - 迷宫.mp3&lt;br /&gt;万芳 - 新不了情.ape&lt;br /&gt;上海电视台小银星合唱团 - 直钩钓鱼情悠悠（《封神榜》插曲）.ape&lt;br /&gt;东方不败 - 伏擊.mp3&lt;br /&gt;东方不败 - 傾心.mp3&lt;br /&gt;东方不败 - 天地醉.mp3&lt;br /&gt;东方不败 - 曲諧.ape&lt;br /&gt;东方不败 - 比劍.mp3&lt;br /&gt;东方不败 - 濃情.mp3&lt;br /&gt;东方不败 - 邂逅.mp3&lt;br /&gt;东邪西毒 - 世事苍茫成云烟(终).mp3&lt;br /&gt;东邪西毒 - 天地孤影任我行(序).mp3&lt;br /&gt;东邪西毒 - 幻影交叠.mp3&lt;br /&gt;东邪西毒 - 情欲流转.mp3&lt;br /&gt;东邪西毒 - 挚爱.mp3&lt;br /&gt;东邪西毒 - 昔情难追.mp3&lt;br /&gt;东邪西毒 - 杀手生涯.mp3&lt;br /&gt;东邪西毒 - 纠结难解.mp3&lt;br /&gt;东邪西毒 - 追忆.mp3&lt;br /&gt;于洋洋 - 十三不亲.mp3&lt;br /&gt;付笛声 - 只见君去不见君还（《康德第一保镖传奇》片头曲）.mp3&lt;br /&gt;任贤齐 - 伤心太平洋（《神雕侠侣》主题曲）.ape&lt;br /&gt;任贤齐 - 天涯 （《笑傲江湖》主题曲）.ape&lt;br /&gt;任静 傅笛声 - 知心爱人.ape&lt;br /&gt;任静 - 蜗牛和黄鹂鸟.ape&lt;br /&gt;伍佰 - 挪威的森林.ape&lt;br /&gt;伍咏薇 - 再生天地（《银狐》主题曲）.mp3&lt;br /&gt;倚天屠龙记 - 两小无猜.ape&lt;br /&gt;倚天屠龙记 - 似水柔情.ape&lt;br /&gt;倚天屠龙记 - 小提琴与乐队.ape&lt;br /&gt;儿童合唱 - 明天会更好.ape&lt;br /&gt;凤飞飞 - 天若有情(《雪山飞狐》粤语片尾曲).ape&lt;br /&gt;凤飞飞 - 莫让红颜守空尘（《雪山飞狐》片尾曲）.ape&lt;br /&gt;刀郎 - 2002年的第一场雪.ape&lt;br /&gt;刀郎 - 情人.ape&lt;br /&gt;刘凤屏 - 八仙过海.mp3&lt;br /&gt;刘家昌、王虹、潘安邦、林灵、千百惠、王立勇、吴涤清、孙国庆 - 今又龙年.ape&lt;br /&gt;刘小慧 - 初恋情人.mp3&lt;br /&gt;刘德华 - Sleeping alone.mp3&lt;br /&gt;刘德华 - 一起走过的日子.ape&lt;br /&gt;刘德华 - 上海滩(粤).mp3&lt;br /&gt;刘德华 - 你是我的女人.ape&lt;br /&gt;刘德华 - 你是我的温柔.ape&lt;br /&gt;刘德华 - 冰雨.ape&lt;br /&gt;刘德华 - 天意.ape&lt;br /&gt;刘德华 - 忘情水.ape&lt;br /&gt;刘德华 - 最孤单的人是我.ape&lt;br /&gt;刘德华 - 最爱上海滩(国).mp3&lt;br /&gt;刘德华 - 真情难收.ape&lt;br /&gt;刘德华 - 真永远.ape&lt;br /&gt;刘德华 - 绝望的笑容.ape&lt;br /&gt;刘德华 - 缘尽.ape&lt;br /&gt;刘德华 - 缠绵.ape&lt;br /&gt;刘德华 - 谢谢你的爱.ape&lt;br /&gt;刘欢 - Vows Were Dreams（《北京人在纽约》主题曲）.ape&lt;br /&gt;刘欢 - 不能这样活（《辘轳·女人和井》片尾曲）.ape&lt;br /&gt;刘欢 - 世界需要热心肠.ape&lt;br /&gt;刘欢 - 人生无悔.mp3&lt;br /&gt;刘欢 - 人生的第一次.mp3&lt;br /&gt;刘欢 - 千万次的问（《北京人在纽约》片头曲）.ape&lt;br /&gt;刘欢 - 好汉歌.mp3&lt;br /&gt;刘欢 - 少年壮志不言愁（《便衣警察》主题歌）.ape&lt;br /&gt;刘欢 - 弯弯的月亮.ape&lt;br /&gt;刘欢 - 心中的太阳（《雪城》主题歌）.ape&lt;br /&gt;刘欢 成方圆 - 谎言（《北京人在纽约》插曲）.ape&lt;br /&gt;刘欢 - 报应（《北京人在纽约》插曲）.ape&lt;br /&gt;刘欢 - 昨天下了一场雨（《山不转水转》片头曲）.ape&lt;br /&gt;刘欢 - 离不开你（《雪城》插曲）.ape&lt;br /&gt;刘欢 - 糊涂的爱（《过把瘾》主题曲）.mp3&lt;br /&gt;刘欢 胡月 - 不能等待.ape&lt;br /&gt;刘畅 黎光 - 河殇-船夫曲.ape&lt;br /&gt;刘若英 - 为爱痴狂.ape&lt;br /&gt;刘若英 - 后来.ape&lt;br /&gt;刘若英 - 很爱很爱你.ape&lt;br /&gt;动力火车 - 当.ape&lt;br /&gt;动力火车 - 忠孝东路走九遍.ape&lt;br /&gt;动力火车 - 无情的情书.ape&lt;br /&gt;动力火车 - 明天的明天的明天.ape&lt;br /&gt;动力火车 - 背叛情歌.ape&lt;br /&gt;千百惠 - 走过咖啡屋.ape&lt;br /&gt;卞留念 - 英雄谁属（《太极宗师》主题曲）.mp3&lt;br /&gt;卢冠廷 - 一生所爱（《大话西游》插曲）.mp3&lt;br /&gt;叶丽仪 - 上海滩.ape&lt;br /&gt;叶丽仪 - 滔滔江水（《再见黄浦滩》主题曲）.mp3&lt;br /&gt;叶丽仪 - 谁令你痴醉（《再见黄浦滩》主题曲）.mp3&lt;br /&gt;叶倩文 - 我的爱对你说.mp3&lt;br /&gt;叶倩文 - 晚风.ape&lt;br /&gt;叶倩文 - 潇洒走一回.ape&lt;br /&gt;叶倩文 - 焚心以火（《古今大战秦俑情》插曲）.ape&lt;br /&gt;叶倩文 - 祝福.ape&lt;br /&gt;叶倩文 - 长夜 MY LOVE GOODNIGHT.ape&lt;br /&gt;叶倩文 - 零时十分.ape&lt;br /&gt;叶倩文 - 黎明不要来（《倩女幽魂》片尾曲）.ape&lt;br /&gt;叶振棠 - 大侠霍元甲.mp3&lt;br /&gt;吕念祖 - 我心中的路.ape&lt;br /&gt;吴晓梅 - 流氓大亨（《流氓大亨》主题曲）.ape&lt;br /&gt;吴鸣 - 情比天地久（《乙未豪客传奇》插曲）.ape&lt;br /&gt;呂珊 - 只记今朝笑(粵)（《东方不败》主题曲）.ape&lt;br /&gt;周华健 - 刀剑如梦（《倚天屠龙记》主题曲）.ape&lt;br /&gt;周华健 成龙 黄耀明 李宗盛 - 真心英雄.ape&lt;br /&gt;周华健 - 我是真的付出我的爱.ape&lt;br /&gt;周华健 - 摆渡人的歌.ape&lt;br /&gt;周华健 - 朋友.ape&lt;br /&gt;周华健 - 难念的经（《天龙八部》主题曲）.mp3&lt;br /&gt;周小君 - 沧海一声笑(断弦版).ape&lt;br /&gt;唐朝 - 不要逃避.ape&lt;br /&gt;唐朝 - 世纪末之梦.ape&lt;br /&gt;唐朝 - 九拍.ape&lt;br /&gt;唐朝 - 传说.ape&lt;br /&gt;唐朝 - 国际歌.ape&lt;br /&gt;唐朝 - 天堂.ape&lt;br /&gt;唐朝 - 太阳.ape&lt;br /&gt;唐朝 - 月梦.ape&lt;br /&gt;唐朝 - 梦回唐朝.ape&lt;br /&gt;唐朝 - 选择.ape&lt;br /&gt;唐朝 - 飞翔鸟.ape&lt;br /&gt;大话西游 - 大圣娶妻之片头曲.mp3&lt;br /&gt;大话西游 - 故事IV.mp3&lt;br /&gt;大话西游 - 西天取经路遥迢.mp3&lt;br /&gt;夫妻对唱 - 夫妻.ape&lt;br /&gt;女声合唱 - 送别.ape&lt;br /&gt;女聲 - 阿瓦尔古麗.ape&lt;br /&gt;姜育恒 - 一世情缘.ape&lt;br /&gt;姜育恒 - 像我这样的人.ape&lt;br /&gt;姜育恒 - 再回首.ape&lt;br /&gt;姜育恒 - 心的另一边（《长相思》主题曲）.ape&lt;br /&gt;姜育恒 - 跟往事干杯.ape&lt;br /&gt;姜育恒 - 驿动的心.ape&lt;br /&gt;孙国庆 - 就恋这把土（《平凡的世界》片头曲）.mp3&lt;br /&gt;孙国庆 - 磨刀老人.ape&lt;br /&gt;孙国庆 - 篱笆墙的影子（《篱笆·女人和狗》主题曲）.ape&lt;br /&gt;孙悦 - 祝你平安.ape&lt;br /&gt;孙燕姿 - 遇见.ape&lt;br /&gt;孙美娜 - 失落的心（《封神榜》插曲）.mp3&lt;br /&gt;孟庭苇 - 一个爱上浪漫的人.ape&lt;br /&gt;孟庭苇 - 你看你看月亮的脸.ape&lt;br /&gt;孟庭苇 - 你究竟有几个好妹妹.ape&lt;br /&gt;孟庭苇 - 其实我还是有点在乎.ape&lt;br /&gt;孟庭苇 - 冬季到台北来看雨.ape&lt;br /&gt;孟庭苇 - 把他换作你.ape&lt;br /&gt;孟庭苇 - 无声的雨.ape&lt;br /&gt;孟庭苇 - 风中有朵雨做的云.ape&lt;br /&gt;屠洪纲 - 独占潇洒（《封神榜》片尾曲）.ape&lt;br /&gt;崔京浩 - 江上行（关羽单刀赴会歌）.ape&lt;br /&gt;崔健 - 一塊紅布.ape&lt;br /&gt;崔健 - 一無所有.ape&lt;br /&gt;崔健 - 假行僧.ape&lt;br /&gt;崔健 - 南泥灣.ape&lt;br /&gt;崔健 - 快讓我在這雪地上撒點野.ape&lt;br /&gt;崔健 - 最后一枪(1988完整版).ape&lt;br /&gt;崔健 - 解決.ape&lt;br /&gt;崔健 - 這兒的空間.ape&lt;br /&gt;庞龙 - 两只蝴蝶.ape&lt;br /&gt;张南雁 - 知我无情有情（《武则天》主题曲）.mp3&lt;br /&gt;张国荣 - 倩女幽魂.ape&lt;br /&gt;张国荣 - 夜半歌声.ape&lt;br /&gt;张国荣 - 奔向未来日子.ape&lt;br /&gt;张国荣 - 当爱已成往事（《霸王别姬》主题曲）.ape&lt;br /&gt;张国荣 - 沉默是金.ape&lt;br /&gt;张国荣 辛晓琪 - 深情相拥.ape&lt;br /&gt;张夏 - 永久有多久.mp3&lt;br /&gt;张学友 汤宝如 - 相思风雨中.ape&lt;br /&gt;张庆祥 - 颠轿歌，大胆往前走.ape&lt;br /&gt;张强 - 烛光里的妈妈.ape&lt;br /&gt;张振富 耿莲凤 - 年轻的朋友来相会.ape&lt;br /&gt;张楚 - 一生祈求.ape&lt;br /&gt;张楚 - 西出阳关.ape&lt;br /&gt;张楚 - 走吧.ape&lt;br /&gt;张继红 - 问情（《戏说乾隆》片头曲）.ape&lt;br /&gt;张艾嘉 - 爱的代价.ape&lt;br /&gt;张艾嘉 - 离开离去.mp3&lt;br /&gt;张行 - 不再孤寂.ape&lt;br /&gt;张行 - 再爱我一次.ape&lt;br /&gt;张行 - 忘了吧.ape&lt;br /&gt;张行 - 恰似你的温柔.ape&lt;br /&gt;张雨生 - 一天到晚游泳的鱼.ape&lt;br /&gt;张雨生 - 大海.ape&lt;br /&gt;张韶涵 - 隐形的翅膀.ape&lt;br /&gt;张飘芳 - 母亲（《亲心唤我心》主题曲）.mp3&lt;br /&gt;張德蘭 - 何日再相見.ape&lt;br /&gt;張德蘭 - 情義兩心堅.ape&lt;br /&gt;張德蘭 - 相識是緣份.ape&lt;br /&gt;張德蘭 - 網中人.ape&lt;br /&gt;張德蘭 - 鮮花滿月樓.ape&lt;br /&gt;彩虹 - 月圆花好.ape&lt;br /&gt;彭丽媛 - 五哥放羊.ape&lt;br /&gt;彭丽媛 - 在希望的田野上.ape&lt;br /&gt;彭丽媛 - 我爱你,塞北的雪.ape&lt;br /&gt;彭丽媛 - 沂蒙山小调.ape&lt;br /&gt;彭丽媛 - 说聊斋.ape&lt;br /&gt;彭丽媛 - 谁不说俺家乡好.ape&lt;br /&gt;徐小凤 - 不了情.ape&lt;br /&gt;徐小凤 - 不夜城传奇（《浮沉》主题曲）.ape&lt;br /&gt;徐小凤 - 今宵多珍重.ape&lt;br /&gt;徐小凤 - 依然.ape&lt;br /&gt;徐小凤 - 城市足印（《流氓大亨》主题曲）.ape&lt;br /&gt;徐小凤 - 如果重相逢（《浮沉》插曲）.ape&lt;br /&gt;徐小凤 - 婚紗背後（《流氓大亨》片尾曲）.ape&lt;br /&gt;徐小凤 - 明月千里寄相思.ape&lt;br /&gt;徐小凤 - 月亮光光.ape&lt;br /&gt;徐小凤 - 每一步.ape&lt;br /&gt;徐小凤 - 问情（《浮沉》插曲）.ape&lt;br /&gt;徐小明 - 再向虎山行.ape&lt;br /&gt;徐玮 - 城市节奏（《调色板》主题曲）.ape&lt;br /&gt;徐玮 - 心动（《调色板》插曲）.ape&lt;br /&gt;徐玮 - 拥抱彩虹（《调色板》插曲）.ape&lt;br /&gt;徐良 彭丽媛 - 血染的风采.ape&lt;br /&gt;成方圆 - 一曲销魂.ape&lt;br /&gt;成方圆 - 掌声响起来.mp3&lt;br /&gt;成龙 - 你给我一片天（《倚天屠龙记》片尾曲）.ape&lt;br /&gt;新上海滩 - 初遇冯程程.mp3&lt;br /&gt;新上海滩 - 友情.mp3&lt;br /&gt;新上海滩 - 死亡.mp3&lt;br /&gt;新上海滩 - 生日舞会.mp3&lt;br /&gt;新上海滩 - 程程的憧憬.mp3&lt;br /&gt;新上海滩 - 许文强与冯程程.mp3&lt;br /&gt;朱明瑛 - 大海啊,故乡.ape&lt;br /&gt;朱晓琳 - 妈妈的吻.ape&lt;br /&gt;朱桦 - 一片田.ape&lt;br /&gt;朱桦 - 七点钟.ape&lt;br /&gt;朱桦 - 三月三.ape&lt;br /&gt;朱桦 - 梦田.ape&lt;br /&gt;朱桦 - 橄榄树.ape&lt;br /&gt;朱桦 - 沙漠.ape&lt;br /&gt;朱桦 - 滚滚红尘.ape&lt;br /&gt;朱桦 - 潇洒人生路.ape&lt;br /&gt;朱桦 - 轨外.ape&lt;br /&gt;朱桦 - 飞.ape&lt;br /&gt;朱茵 - 追梦（《大话西游》插曲）.mp3&lt;br /&gt;李克勤 - 红日.ape&lt;br /&gt;李力 - 海灯法师.mp3&lt;br /&gt;李圣杰 - 痴心绝对.ape&lt;br /&gt;李娜 - 女人是老虎.ape&lt;br /&gt;李娜 - 好人一生平安（《渴望》片头曲）.ape&lt;br /&gt;李娜 - 嫂子颂（《赵尚志》片尾曲）.ape&lt;br /&gt;李娜 - 相逢.ape&lt;br /&gt;李娜 - 苦篱笆（《篱笆·女人和狗》插曲）.ape&lt;br /&gt;李娜 - 青藏高原.ape&lt;br /&gt;李宗盛 - 鬼迷心窍（《末龙》主题曲）.ape&lt;br /&gt;李小文 - 过三关（《篱笆·女人和狗》插曲）.ape&lt;br /&gt;李度 周华健 - 难以抗拒.mp3&lt;br /&gt;李建复 - 龙的传人.mp3&lt;br /&gt;李玲玉 - 沈阳我的故乡.ape&lt;br /&gt;李碧华 - 不如归去（《庭院深深》插曲）.ape&lt;br /&gt;李碧华 - 庭院深深.ape&lt;br /&gt;李福山 - 一剪梅.ape&lt;br /&gt;李翊君 - 冲不破情网.mp3&lt;br /&gt;李翊君 - 婉君.mp3&lt;br /&gt;李翊君 - 痛.mp3&lt;br /&gt;李翊君 - 雨蝶.ape&lt;br /&gt;李谷一 - 乡恋.ape&lt;br /&gt;李谷一 - 天涯歌女.ape&lt;br /&gt;李谷一 - 知音.ape&lt;br /&gt;李谷一 - 难忘今宵.ape&lt;br /&gt;李进 - 你在他乡还好吗.ape&lt;br /&gt;杜德伟 - 情人.ape&lt;br /&gt;杨庆煌 - 我有一片心（《雪山飞狐》插曲）.ape&lt;br /&gt;杨庆煌 - 雪中情.ape&lt;br /&gt;杨紫琼 - 爱似流星（《新流星蝴蝶剑》主题曲）.ape&lt;br /&gt;杨钰莹 - 因为有你.mp3&lt;br /&gt;杨钰莹 - 我不想说（《外来妹》主题曲）.ape&lt;br /&gt;杨钰莹 - 轻轻地告诉你.ape&lt;br /&gt;杨鸿基 - 滚滚长江东逝水（《三国演义》主题曲）.ape&lt;br /&gt;杨鸿基 - 短歌行（曹操横槊赋诗歌）.ape&lt;br /&gt;杭天棋 - 爱并不遥远.mp3&lt;br /&gt;杭天琪 - 不能这样活（《辘轳·女人和井》插曲）.ape&lt;br /&gt;杭天琪 - 追缘.ape&lt;br /&gt;杭天琪 - 高天上流云.ape&lt;br /&gt;杭天琪 - 黄河源头.ape&lt;br /&gt;杭天琪 - 黑头发飘起来.mp3&lt;br /&gt;杭宏 - 相约如梦（《北京人在纽约》主题曲）.ape&lt;br /&gt;林子祥 - 人海中一个你.ape&lt;br /&gt;林忆莲 - 伤痕.ape&lt;br /&gt;林忆莲 - 爱上一个不回家的人.ape&lt;br /&gt;林忆莲 - 至少还有你.ape&lt;br /&gt;林淑容 - 昨夜星辰.ape&lt;br /&gt;林灵 - 像风一样（《情义无价》片尾曲）.ape&lt;br /&gt;林灵 - 情义无价.ape&lt;br /&gt;林青霞 - 只记今朝笑.ape&lt;br /&gt;林青霞 - 天地醉(國).mp3&lt;br /&gt;梁朝伟 - 一天一点爱恋.ape&lt;br /&gt;梁朝伟 张曼玉 - 花样年华.mp3&lt;br /&gt;梁朝伟 - 愿你知我心（《绝代双骄》主题曲）.mp3&lt;br /&gt;梁静茹 - Fly away.ape&lt;br /&gt;梁静茹 - 勇气.ape&lt;br /&gt;梁静茹 - 宁夏.ape&lt;br /&gt;梅艳芳 - 亲密爱人.ape&lt;br /&gt;梅艳芳 - 似是故人来.ape&lt;br /&gt;梅艳芳 - 女人花.ape&lt;br /&gt;梅艳芳 - 胭脂扣.ape&lt;br /&gt;森森 - 何日刀锋断我愁（《天涯明月刀》主题曲）.ape&lt;br /&gt;段品章 - 天长地久（《审计备忘录》主题歌）.ape&lt;br /&gt;段品章 - 岁月如流.ape&lt;br /&gt;毛宁 杨钰莹 - 心雨.ape&lt;br /&gt;毛宁 - 涛声依旧.ape&lt;br /&gt;毛宁 - 等你在老地方（《外来妹》片尾曲）.ape&lt;br /&gt;毛阿敏 - 不白活一回.ape&lt;br /&gt;毛阿敏 - 也许折腾就是爱.ape&lt;br /&gt;毛阿敏 - 人生一世（《皇城根儿》片尾曲）.ape&lt;br /&gt;毛阿敏 - 什么也没有说.ape&lt;br /&gt;毛阿敏 - 伤别离（《金镖黄天霸》插曲）.ape&lt;br /&gt;毛阿敏 - 几度夕阳红.ape&lt;br /&gt;毛阿敏 刘欢 - 奥林匹克风.mp3&lt;br /&gt;毛阿敏 - 北方飞来的天鹅.ape&lt;br /&gt;毛阿敏 - 历史的天空（《三国演义》片尾曲）.ape&lt;br /&gt;毛阿敏 - 双离雁（《平凡的世界》插曲）.mp3&lt;br /&gt;毛阿敏 - 同一首歌.ape&lt;br /&gt;毛阿敏 - 女人不是月亮.ape&lt;br /&gt;毛阿敏 - 往事成烟.ape&lt;br /&gt;毛阿敏 - 心世界.ape&lt;br /&gt;毛阿敏 - 思念.ape&lt;br /&gt;毛阿敏 - 情锁.ape&lt;br /&gt;毛阿敏 - 我不想再次被情伤.ape&lt;br /&gt;毛阿敏 - 我想有个家.ape&lt;br /&gt;毛阿敏 - 投入的爱一次（《编辑部的故事》片尾曲）.ape&lt;br /&gt;毛阿敏 - 拼图.ape&lt;br /&gt;毛阿敏 - 无论多久.ape&lt;br /&gt;毛阿敏 - 永远是朋友.ape&lt;br /&gt;毛阿敏 - 洒向人间都是爱.mp3&lt;br /&gt;毛阿敏 - 渴望.ape&lt;br /&gt;毛阿敏 - 濛濛烟雨.ape&lt;br /&gt;毛阿敏 - 爱上张无忌.ape&lt;br /&gt;毛阿敏 - 爱（《平凡的世界》插曲）.mp3&lt;br /&gt;毛阿敏 - 神的传说（《封神榜》片头曲）.ape&lt;br /&gt;毛阿敏 - 篱笆墙的影子（《篱笆·女人和狗》主题曲）.ape&lt;br /&gt;毛阿敏 - 绿叶对根的情意.ape&lt;br /&gt;毛阿敏 - 美满.ape&lt;br /&gt;毛阿敏 - 莫忘今宵情.ape&lt;br /&gt;毛阿敏 - 诺言.ape&lt;br /&gt;毛阿敏 - 都说人生像大海（《无敌鸳鸯腿》插曲）.ape&lt;br /&gt;毛阿敏 - 闯平川.ape&lt;br /&gt;江淑娜 - 谈笑一生.ape&lt;br /&gt;江珊 - 梦里水乡.ape&lt;br /&gt;汪明荃 - 用愛將心偷.ape&lt;br /&gt;汪明荃 - 萬水千山總是情.ape&lt;br /&gt;滄海一聲笑斷弦版(粵) - 斷弦.mp3&lt;br /&gt;潘越雲 - 痴情不是一種罪過.ape&lt;br /&gt;王子鸣 - 说好秋天就回来.ape&lt;br /&gt;王杰 - 一场游戏一场梦.ape&lt;br /&gt;王杰 叶欢 - 你是我胸口永远的痛.ape&lt;br /&gt;王杰 - 回家.ape&lt;br /&gt;王杰 - 她的背影.ape&lt;br /&gt;王杰 - 孤星.ape&lt;br /&gt;王杰 - 是否我真的一无所有.ape&lt;br /&gt;王杰 - 来生再续缘.mp3&lt;br /&gt;王茜 - 读你.ape&lt;br /&gt;王菲 - Eyes On Me.ape&lt;br /&gt;王菲 - 人间.ape&lt;br /&gt;王菲 - 传奇.ape&lt;br /&gt;王菲 - 你快乐(所以我快乐).ape&lt;br /&gt;王菲 - 南海姑娘.ape&lt;br /&gt;王菲 - 只愿为你守着约.ape&lt;br /&gt;王菲 - 四月雪.ape&lt;br /&gt;王菲 - 天与地.ape&lt;br /&gt;王菲 - 如风.ape&lt;br /&gt;王菲 - 季侯风.ape&lt;br /&gt;王菲 - 容易受伤的女人(国).ape&lt;br /&gt;王菲 - 容易受伤的女人(粤).ape&lt;br /&gt;王菲 - 尾班车.ape&lt;br /&gt;王菲 - 当时的月亮.ape&lt;br /&gt;王菲 - 我愿意(国).ape&lt;br /&gt;王菲 - 执迷不悔(国).ape&lt;br /&gt;王菲 - 执迷不悔(粤).ape&lt;br /&gt;王菲 - 旋木.ape&lt;br /&gt;王菲 - 无奈那天.ape&lt;br /&gt;王菲 - 暗涌.ape&lt;br /&gt;王菲 - 暧昧.ape&lt;br /&gt;王菲 - 梦中人.ape&lt;br /&gt;王菲 - 流年.ape&lt;br /&gt;王菲 - 爱与痛的边缘.ape&lt;br /&gt;王菲 - 知已知彼.ape&lt;br /&gt;王菲 - 空城.ape&lt;br /&gt;王菲 - 笑忘书.ape&lt;br /&gt;王菲 - 红豆.ape&lt;br /&gt;王菲 - 约定.ape&lt;br /&gt;王菲 - 给自己的情书.ape&lt;br /&gt;王菲 - 胡思乱相.ape&lt;br /&gt;王菲 - 蝴蝶.ape&lt;br /&gt;王菲 那英 - 相约一九九八.ape&lt;br /&gt;王菲 - 闷.ape&lt;br /&gt;王菲 - 静夜的单簧管.ape&lt;br /&gt;王虹 - 血染的风采.ape&lt;br /&gt;王靖雯 - 不變.ape&lt;br /&gt;王靖雯 - 天空.ape&lt;br /&gt;王靖雯 - 天空(Unplugged).ape&lt;br /&gt;王靖雯 - 影子.ape&lt;br /&gt;王靖雯 - 掙脫.ape&lt;br /&gt;王靖雯 - 棋子.ape&lt;br /&gt;王靖雯 - 矜持.ape&lt;br /&gt;王馨平 - 一生痴恋(国).ape&lt;br /&gt;王馨平 - 不要躲避我的眼睛（《中南海保镖》主题曲）.ape&lt;br /&gt;王馨平 - 别问我是谁(国).ape&lt;br /&gt;王馨平 高明駿 - 今生註定.mp3&lt;br /&gt;甄妮 - 肯去承擔愛.ape&lt;br /&gt;白冰 - 希望.mp3&lt;br /&gt;程琳 - 风雨兼程.ape&lt;br /&gt;窦鹏 - 思故乡.ape&lt;br /&gt;童声合唱 - 世界很小是个小家庭（《编辑部的故事》插曲）.mp3&lt;br /&gt;童安格 - 明天你是否依然爱我.ape&lt;br /&gt;童聲 - 送別.ape&lt;br /&gt;红楼梦.王洁实 - 聪明累.ape&lt;br /&gt;红楼梦.王洁实 陈力 - 红豆曲.ape&lt;br /&gt;红楼梦.王立平 - 好了歌.ape&lt;br /&gt;红楼梦.陈力 - 分骨肉.ape&lt;br /&gt;红楼梦.陈力 - 叹香菱.ape&lt;br /&gt;红楼梦.陈力 - 引子.ape&lt;br /&gt;红楼梦.陈力 - 晴雯歌.ape&lt;br /&gt;红楼梦.陈力 - 枉凝眉.ape&lt;br /&gt;红楼梦.陈力 - 秋窗风雨夕.ape&lt;br /&gt;红楼梦.陈力 - 紫菱洲歌.ape&lt;br /&gt;红楼梦.陈力 - 葬花吟.ape&lt;br /&gt;红楼梦.陈力 - 题帕三绝.ape&lt;br /&gt;纪如璟 - 值得一辈子去爱.ape&lt;br /&gt;纪如璟 - 寂寞的自由.ape&lt;br /&gt;纪晓兰 - 妲己吟（《封神榜》插曲）.ape&lt;br /&gt;罗嘉良 - 大地在我脚下（《秦始皇》主题曲）.mp3&lt;br /&gt;罗文 - 八月桂花香（《八月桂花香》片头曲）.ape&lt;br /&gt;罗文 甄妮 - 一生有意义（《射雕英雄传之东邪西毒》主题曲）.ape&lt;br /&gt;罗文 甄妮 - 世间始终你好（《射雕英雄传之华山论剑》主题曲）.ape&lt;br /&gt;罗文 甄妮 - 铁血丹心（《射雕英雄传之铁血丹心》主题曲）.ape&lt;br /&gt;罗西 - 一封无法投递的信.ape&lt;br /&gt;羅大佑 - 你的樣子.ape&lt;br /&gt;羅大佑 - 光陰的故事.ape&lt;br /&gt;羅大佑 - 吾鄉印象.ape&lt;br /&gt;羅大佑 - 告別的年代.ape&lt;br /&gt;羅大佑 - 家Ⅱ.ape&lt;br /&gt;羅大佑 - 愛的箴言.ape&lt;br /&gt;羅大佑 - 戀曲1980.ape&lt;br /&gt;羅大佑 - 戀曲1990.ape&lt;br /&gt;羅大佑 - 戀曲2000.ape&lt;br /&gt;羅大佑 - 未來的主人翁.ape&lt;br /&gt;羅大佑 - 歌.ape&lt;br /&gt;羅大佑 - 海上花.ape&lt;br /&gt;羅大佑 - 穿過你的黑髮的我的手.ape&lt;br /&gt;羅大佑 - 鄉愁四韻.ape&lt;br /&gt;羅大佑 - 野百合也有春天.ape&lt;br /&gt;羅大佑 - 閃亮的日子.ape&lt;br /&gt;羅大佑 - 風兒你在輕輕的吹.ape&lt;br /&gt;羅文 - 人間.ape&lt;br /&gt;羅文 - 小李飛刀.ape&lt;br /&gt;群星 - 历史的伤口.ape&lt;br /&gt;群星 - 奥林匹克风.mp3&lt;br /&gt;群星 - 明天会更好.ape&lt;br /&gt;群星 - 最好的聲音.mp3&lt;br /&gt;群星 - 让世界充满爱-走向明天.ape&lt;br /&gt;翁倩玉 - Charm.ape&lt;br /&gt;翁倩玉 - 爱的奉献.ape&lt;br /&gt;翁倩玉 - 祈祷.ape&lt;br /&gt;翁素英 - 人在旅途.ape&lt;br /&gt;翟惠民 - 十不该.ape&lt;br /&gt;翟惠民 - 狱中十二月.ape&lt;br /&gt;翟惠民 - 蚂蚱.ape&lt;br /&gt;翟惠民 - 钞票.ape&lt;br /&gt;胡月 - 周末PARTY.ape&lt;br /&gt;胡月 - 小城风雨情（《小城故事》主题曲）.ape&lt;br /&gt;胡月 - 我是一只小海螺.ape&lt;br /&gt;胡月 - 我热恋的故乡.ape&lt;br /&gt;胡月 - 走西口.ape&lt;br /&gt;臧天朔 - 朋友.ape&lt;br /&gt;花样年华.Nat King Cole - Aquellos Ojos Verdes.ape&lt;br /&gt;花样年华.Nat King Cole - Quizas, Quizas, Quizas (Perhaps, Perhaps, Perhaps).ape&lt;br /&gt;花样年华 - Yumeji's Theme.ape&lt;br /&gt;苏红 - 月亮走我也走.ape&lt;br /&gt;苏红 - 香客.ape&lt;br /&gt;苏芮 - CHANGES.ape&lt;br /&gt;苏芮 - 亲爱的小孩.ape&lt;br /&gt;苏芮 - 再回首.ape&lt;br /&gt;苏芮 - 奉献.ape&lt;br /&gt;苏芮 - 牵手.ape&lt;br /&gt;苏芮 虞战平 - 请跟我来.ape&lt;br /&gt;苏芮 - 跟着感觉走.ape&lt;br /&gt;苏芮 - 酒干倘卖无.ape&lt;br /&gt;范春梅 - 月亮之歌（《凯旋在子夜》插曲）.mp3&lt;br /&gt;范晓萱 - 深呼吸.ape&lt;br /&gt;范琳琳 - 一片热土.ape&lt;br /&gt;范琳琳 - 一首小诗.ape&lt;br /&gt;范琳琳 - 不要逼我说话（《康德第一保镖传奇》插曲）.mp3&lt;br /&gt;范琳琳 - 为了寻求美.ape&lt;br /&gt;范琳琳 - 信天游.ape&lt;br /&gt;范琳琳 - 十五的月儿十六圆.ape&lt;br /&gt;范琳琳 - 平凡的世界（《平凡的世界》片尾曲）.mp3&lt;br /&gt;范琳琳 - 我们与世界.mp3&lt;br /&gt;范琳琳 - 我热恋的故乡.ape&lt;br /&gt;范琳琳 - 故土难离（《平凡的世界》插曲）.mp3&lt;br /&gt;范琳琳 - 来自心海的消息.ape&lt;br /&gt;范琳琳 - 红萝卜.mp3&lt;br /&gt;范琳琳 - 苦乐年华（《篱笆·女人和狗》片尾曲）.ape&lt;br /&gt;范琳琳 - 西部之恋.ape&lt;br /&gt;范琳琳 - 黄土高坡.ape&lt;br /&gt;范琳琳 - 黑头发，飘起来.ape&lt;br /&gt;莫文蔚 - 未了情（《大话西游》插曲）.mp3&lt;br /&gt;葉歡 - 鴛鴦錦.ape&lt;br /&gt;蒋大为 - 在那桃花盛开的地方.mp3&lt;br /&gt;蒋大为 - 牡丹之歌.ape&lt;br /&gt;蔡幸娟 - 我心已許.ape&lt;br /&gt;蔡幸娟 - 星星知我心.mp3&lt;br /&gt;蔡幸娟 - 问情（《戏说乾隆》主题曲）.ape&lt;br /&gt;蔡琴 - 你的眼神.ape&lt;br /&gt;蔡琴 - 渡口.ape&lt;br /&gt;衡越 - 谁是我的新郎（《乡村爱情》片尾曲）.mp3&lt;br /&gt;西游记.丁小青 - 被贬五行山.ape&lt;br /&gt;西游记 - 初到女儿国.mp3&lt;br /&gt;西游记.叶矛 - 无底船歌.mp3&lt;br /&gt;西游记.吴静 - 何必西天万里遥.ape&lt;br /&gt;西游记.吴静 - 女儿情.mp3&lt;br /&gt;西游记.吴静 - 相见难别亦难.mp3&lt;br /&gt;西游记 - 天府乐.mp3&lt;br /&gt;西游记.女声合唱 - 西游记主题曲.ape&lt;br /&gt;西游记 - 安天会.mp3&lt;br /&gt;西游记.张徐 - 逍遥自在的孙大圣.ape&lt;br /&gt;西游记.张暴默 - 敢问路在何方.ape&lt;br /&gt;西游记.成都市西城区少年宫合唱团 - 官封弼马温.ape&lt;br /&gt;西游记.李玲玉 - 天竺少女.mp3&lt;br /&gt;西游记.李静娴 - 走啊走.mp3&lt;br /&gt;西游记.李静娴 - 青青菩提树.mp3&lt;br /&gt;西游记 - 江月.mp3&lt;br /&gt;西游记.混声合唱 - 风雨行路难.ape&lt;br /&gt;西游记 - 片头曲.mp3&lt;br /&gt;西游记.王小青 - 生无名，本无姓.ape&lt;br /&gt;西游记.胡寅寅 - 孙悟空之歌.ape&lt;br /&gt;西游记.蒋大为 - 取经歌.mp3&lt;br /&gt;西游记.蒋大为 - 敢问路在何方.mp3&lt;br /&gt;西游记.西游记剧组全体演员 - 贺新春.ape&lt;br /&gt;西游记.贾兵 - 猪八戒背媳妇.ape&lt;br /&gt;西游记.迟重瑞 - 唐僧抒怀.mp3&lt;br /&gt;西游记.迟重瑞 - 晴空月儿明.mp3&lt;br /&gt;西游记.郁钧剑 - 五百年桑田沧海.ape&lt;br /&gt;西游记.郁钧剑 - 吹不散这点点愁.ape&lt;br /&gt;西游记.马国光 - 猪八戒之歌.ape&lt;br /&gt;西游记 - 鸳鸯梦.mp3&lt;br /&gt;解晓东 - 每一次（《渴望》插曲）.ape&lt;br /&gt;解晓卫 - 那根藤缠树（《辘轳·女人和井》插曲）.ape&lt;br /&gt;许冠杰 - 浪子心声.ape&lt;br /&gt;许志安 - 爱的记号（《上海大风暴》主题曲）.ape&lt;br /&gt;许美静 - 倾城.ape&lt;br /&gt;许美静 - 城里的月光.ape&lt;br /&gt;许美静 - 如此.ape&lt;br /&gt;许美静 - 带我走.ape&lt;br /&gt;许美静 - 明知故犯（香港版）.ape&lt;br /&gt;许美静 - 都是夜归人.ape&lt;br /&gt;许美静 - 铁窗.ape&lt;br /&gt;许美静 - 阳光总在风雨后.ape&lt;br /&gt;费玉清 - 一剪梅.ape&lt;br /&gt;赵莉 - 几度夕阳红.ape&lt;br /&gt;辛晓琪 - 俩俩相忘（《倚天屠龙记》插曲）.ape&lt;br /&gt;辛晓琪 - 味道.ape&lt;br /&gt;辛晓琪 - 深情难了.ape&lt;br /&gt;辛晓琪 - 走过.ape&lt;br /&gt;辛晓琪 - 领悟.ape&lt;br /&gt;邓丽君 - 在水一方.ape&lt;br /&gt;邓丽君 - 夜来香.ape&lt;br /&gt;邓丽君 - 浪子心声.ape&lt;br /&gt;邓丽君 - 漫步人生路.ape&lt;br /&gt;邓丽君 - 路边的野花不要采.ape&lt;br /&gt;邓启平 - 人生（《海灯法师》片尾曲）.mp3&lt;br /&gt;邝美云 - 我和春天有個約會.mp3&lt;br /&gt;邝美云 - 还有明天（《边城浪子》主题曲）.ape&lt;br /&gt;那英 - 一笑而过.ape&lt;br /&gt;那英 - 不能没有你.ape&lt;br /&gt;那英 - 为你心甘情愿.ape&lt;br /&gt;那英 - 为你朝思暮想.ape&lt;br /&gt;那英 - 五彩路.ape&lt;br /&gt;那英 - 但愿好梦都成真.ape&lt;br /&gt;那英 - 关于昨夜.ape&lt;br /&gt;那英 - 千万次的问（《北京人在纽约》片头曲）.ape&lt;br /&gt;那英 - 好大一棵树.ape&lt;br /&gt;那英 - 山不转水转.ape&lt;br /&gt;那英 - 山沟沟.ape&lt;br /&gt;那英 - 愿赌服输.ape&lt;br /&gt;那英 - 我来因为你在.ape&lt;br /&gt;那英 - 报应（《北京人在纽约》片尾曲）.ape&lt;br /&gt;那英 - 拥抱明天.mp3&lt;br /&gt;那英 - 欲走还留.ape&lt;br /&gt;那英 - 沙棘花.ape&lt;br /&gt;那英 - 爱上你等于爱上寂寞.mp3&lt;br /&gt;那英 - 白天不懂夜的黑.ape&lt;br /&gt;那英 - 相见不如怀念.ape&lt;br /&gt;那英 - 给你的.ape&lt;br /&gt;那英 - 走出沼泽.ape&lt;br /&gt;那英 - 还要再见面.ape&lt;br /&gt;那英 - 醒时作梦.ape&lt;br /&gt;那英 - 雾里看花.ape&lt;br /&gt;那英 - 青青世界.ape&lt;br /&gt;邰正宵 - 九百九十九朵玫瑰.ape&lt;br /&gt;邰正宵 - 千纸鹤.ape&lt;br /&gt;邰正宵 - 找一个字代替.ape&lt;br /&gt;邹军 - 妹妹你大胆往前走（《红高粱》插曲）.ape&lt;br /&gt;邹军 - 酒神曲.ape&lt;br /&gt;郑绪岚 - 牧羊曲（《少林寺》插曲）.ape&lt;br /&gt;郭公芳 - 人人有本难念的经.ape&lt;br /&gt;鄧麗君 - 何日君再來.ape&lt;br /&gt;鄧麗君 - 假如我是真的.ape&lt;br /&gt;鄧麗君 - 再見!我的愛人.ape&lt;br /&gt;鄧麗君 - 小城故事.ape&lt;br /&gt;鄧麗君 - 恰似你的溫柔.ape&lt;br /&gt;鄧麗君 - 情人的關懷.ape&lt;br /&gt;鄧麗君 - 愛像一首歌.ape&lt;br /&gt;鄧麗君 - 我只在乎你.ape&lt;br /&gt;鄧麗君 - 春風滿小城.ape&lt;br /&gt;鄧麗君 - 月亮代表我的心.ape&lt;br /&gt;鄧麗君 - 梅花.ape&lt;br /&gt;鄧麗君 - 海韻.ape&lt;br /&gt;鄧麗君 - 甜蜜蜜.ape&lt;br /&gt;鄧麗君 - 風兒雨兒.ape&lt;br /&gt;鄭智化、岳翎 - 相認.ape&lt;br /&gt;重庆森林 - 伤心短篇.mp3&lt;br /&gt;重庆森林 - 分手前最后一声再见.mp3&lt;br /&gt;重庆森林 - 夜餐.mp3&lt;br /&gt;重庆森林 - 感性森林.mp3&lt;br /&gt;重庆森林 - 汗、雨、泪.mp3&lt;br /&gt;重庆森林 - 追逐一班行而上列车.mp3&lt;br /&gt;金学峰 - 心爱（《倚天屠龙记》主题曲）.ape&lt;br /&gt;金学峰 - 老乡.ape&lt;br /&gt;钟镇涛 - 只要你过得比我好.ape&lt;br /&gt;钟镇涛 章蓉舫 - 你是我心底的烙印.ape&lt;br /&gt;陈亮吟 - 不让余恨留在人间（《八月桂花香》片尾曲）.ape&lt;br /&gt;陈奕迅 - 十年.ape&lt;br /&gt;陈慧娴 - 与泪拥抱.ape&lt;br /&gt;陈慧娴 - 人生何处不相逢.ape&lt;br /&gt;陈慧娴 - 千千阙歌.ape&lt;br /&gt;陈慧娴 - 去吧.ape&lt;br /&gt;陈慧娴 - 夜机.ape&lt;br /&gt;陈慧娴 - 孤单背影.ape&lt;br /&gt;陈慧娴 - 月亮.ape&lt;br /&gt;陈慧娴 - 真情流露.ape&lt;br /&gt;陈慧娴 - 跳舞街.ape&lt;br /&gt;陈慧娴 - 逝去的诺言.ape&lt;br /&gt;陈慧娴 - 飘雪.ape&lt;br /&gt;陈明 - 为你.ape&lt;br /&gt;陈明真 - 我用自己的方式爱你.ape&lt;br /&gt;陈淑桦 - 梦醒时分.ape&lt;br /&gt;陈淑桦 - 滚滚红尘.ape&lt;br /&gt;陈淑桦 - 笑红尘（《东方不败之风云再起》主题曲）.ape&lt;br /&gt;陈淑桦 - 笑红尘(粤).mp3&lt;br /&gt;陈百强 - 一生何求.ape&lt;br /&gt;陈百强 - 偏偏喜欢你.ape&lt;br /&gt;陈秀雯 - 艳阳.ape&lt;br /&gt;陈红 - 常回家看看.ape&lt;br /&gt;零点乐队 - 爱不爱我.ape&lt;br /&gt;韦唯 刘欢 - 亚洲雄风.ape&lt;br /&gt;韦唯 - 命运不是辘轳（《辘轳·女人和井》主题曲）.ape&lt;br /&gt;韦唯 - 心愿.ape&lt;br /&gt;韦唯 - 风雨真情（《人间芙蓉色》主题曲）.ape&lt;br /&gt;韩宝仪 - 粉红色的回忆.ape&lt;br /&gt;风哥 - 含泪跳恰恰.mp3&lt;br /&gt;风哥 - 夜上海+满场飞.mp3&lt;br /&gt;风哥 - 扇子舞.mp3&lt;br /&gt;风哥 - 校园的早晨.mp3&lt;br /&gt;风哥 - 烈女.mp3&lt;br /&gt;风哥 - 跳舞到天光.mp3&lt;br /&gt;风哥 - 采茶舞曲.mp3&lt;br /&gt;騰格尔 - 天堂.ape&lt;br /&gt;高林生 - 牵挂你的人是我.ape&lt;br /&gt;高枫 - 一份安慰（《皇城根儿》主题曲）.ape&lt;br /&gt;高枫 - 来生再续缘（《戏说乾隆》片尾曲）.ape&lt;br /&gt;高胜美 - 千年等一回.mp3&lt;br /&gt;高胜美 - 庭院深深.ape&lt;br /&gt;高胜美 - 青青河边草.mp3&lt;br /&gt;黃鶯鶯 - 哭砂.ape&lt;br /&gt;黃鶯鶯 - 葬心.ape&lt;br /&gt;黄仲坤 - 有多少爱可以重来.mp3&lt;br /&gt;黄凯芹 - 晚秋.ape&lt;br /&gt;黄品源 - 你怎么舍得我难过.ape&lt;br /&gt;黄品源 - 小薇.ape&lt;br /&gt;黄品源 - 海浪.ape&lt;br /&gt;黄大炜 - 你把我灌醉.mp3&lt;br /&gt;黄安 - 新鸳鸯蝴蝶梦.ape&lt;br /&gt;黄霑 徐克 罗大佑 - 沧海一声笑（《笑傲江湖》主题曲）.ape&lt;br /&gt;黑豹 - Don't Break My Heart.ape&lt;br /&gt;黑豹 - Take Care.ape&lt;br /&gt;黑豹 - 别去糟蹋.ape&lt;br /&gt;黑豹 - 脸谱.ape&lt;br /&gt;齐秦 - 不如這樣吧.ape&lt;br /&gt;齐秦 - 不讓我的眼淚陪我過夜.ape&lt;br /&gt;齐秦 - 丝路.ape&lt;br /&gt;齐秦 - 冬雨.ape&lt;br /&gt;齐秦 - 命運的深淵.ape&lt;br /&gt;齐秦 - 外面的世界.ape&lt;br /&gt;齐秦 - 夜夜夜夜.ape&lt;br /&gt;齐秦 - 大约在冬季.ape&lt;br /&gt;齐秦 - 往事隨風.ape&lt;br /&gt;齐秦 - 愛情宣言.ape&lt;br /&gt;齐秦 - 懸崖.ape&lt;br /&gt;齐秦 - 火柴天堂.ape&lt;br /&gt;齐秦 - 無情的雨無情的你.ape&lt;br /&gt;齐秦 - 狼.ape&lt;br /&gt;齐秦 - 直到世界末日.ape&lt;br /&gt;齐秦 - 這一次我絕不放手.ape&lt;br /&gt;齐豫 - Tears.ape&lt;br /&gt;齐豫 周华健 - 天下有情人.ape&lt;br /&gt;齐豫 - 橄榄树.ape&lt;br /&gt;齐豫 - 走在雨中.ape&lt;br /&gt;&lt;br /&gt;eng:&lt;br /&gt;Ace Of Base - Beautiful Life.ape&lt;br /&gt;A Fistful of Dollars - Titoli.ape&lt;br /&gt;Bach - Minuet.ape&lt;br /&gt;Beethoven - Pathetic Sonata.ape&lt;br /&gt;Bertie Higgins - Casablanca.ape&lt;br /&gt;Bizet - Marche du toreador.ape&lt;br /&gt;Bohn Barry - Body Heat.ape&lt;br /&gt;Brother.久石譲 - Ballade.ape&lt;br /&gt;Bruce Broughton - Silverado.ape&lt;br /&gt;Carpenters - Yesterday Once More.ape&lt;br /&gt;Chopin - E major, Tristesse (Sadness).ape&lt;br /&gt;Chopin - Fantasie Impromptu.ape&lt;br /&gt;Chopin - 夜想曲第２０番嬰ハ短調（遺作）.mp3&lt;br /&gt;Christopher Palmer - Anthology Of TV Western Themes.ape&lt;br /&gt;Dance - 小白花（Rumba）.ape&lt;br /&gt;Dance - 旅伴（Tango）.ape&lt;br /&gt;Dance - 黄色衬衣（快四）.ape&lt;br /&gt;Diego Modena - Implora.ape&lt;br /&gt;Dimitri Tiomkin - Gunfight At The OK Corral.ape&lt;br /&gt;Dvorak - New World Symphony.ape&lt;br /&gt;Eagles - Hotel California.ape&lt;br /&gt;Elmer Bernstein - The Magnificent Seven.ape&lt;br /&gt;Ennio Morricone - Chi Mai.ape&lt;br /&gt;Ennio Morricone - For A Few Dollars More.ape&lt;br /&gt;ERA - The Champions.ape&lt;br /&gt;ERA - The Mass.ape&lt;br /&gt;Eva - Fields Of Gold.ape&lt;br /&gt;Fool's Garden - Lemon Tree.ape&lt;br /&gt;Francois Feldman - Magic' boul'vard.ape&lt;br /&gt;Franz Waxman - The Furies Suite.ape&lt;br /&gt;Guitar - Scarborough Fair.ape&lt;br /&gt;HANA-BI.久石譲 - Angel.ape&lt;br /&gt;HANA-BI.久石譲 - HANA-BI.ape&lt;br /&gt;HANA-BI.久石譲 - Painters.ape&lt;br /&gt;HDimitri Tiomkin - High Noon.ape&lt;br /&gt;Jackie Brown.Bobby Womack - Across 110Th Street.ape&lt;br /&gt;Jackie Brown.Brothers Johnson - Strawberrry Letter #23.ape&lt;br /&gt;Jackie Brown.Randy Crawford - Street Life.ape&lt;br /&gt;James Horner - Enemy At the Gates.ape&lt;br /&gt;James Horner - Legends of the Fall.ape&lt;br /&gt;Jean-Claude Borelly  - Dolannes Melodie.ape&lt;br /&gt;Jerome Moross - The Big Country.ape&lt;br /&gt;John Williams - Across The Star.mp3&lt;br /&gt;Kelly Sweet - Ready For Love.ape&lt;br /&gt;Kenny G - Going Home.ape&lt;br /&gt;Khatchaturian - Sabre Dance.ape&lt;br /&gt;Kill Bill II.Charlie Feathers - Can't Hardly Stand It.ape&lt;br /&gt;Kill Bill II.Shivaree - Goodnight Moon.ape&lt;br /&gt;Kill Bill I.Meiko Kaji - The Flower Of Carnage.ape&lt;br /&gt;Kill Bill I.Tomoyasu Hotei - Battle Without Honor Or Humanity.ape&lt;br /&gt;Kill Bill I.Zamfir - The Lonely Shepherd.ape&lt;br /&gt;Koreana - HAND IN HAND.ape&lt;br /&gt;Koreana - STAY.ape&lt;br /&gt;Liszt - Liebestraum.ape&lt;br /&gt;Maksim - Hana's Eyes.ape&lt;br /&gt;Mission Impossible.Danny Elfman - Dreams.ape&lt;br /&gt;Mission Impossible.Danny Elfman - Main Theme.ape&lt;br /&gt;Mission Impossible.Danny Elfman - Theme2.ape&lt;br /&gt;NHK.63億人の地図.大島ミチル - Main Theme（Piano Solo）.ape&lt;br /&gt;NHK.63億人の地図.大島ミチル - 宇宙の大地.ape&lt;br /&gt;NHK.JAPANデビュー.加古隆 - Main Theme.mp3&lt;br /&gt;NHK.中國～12儀人の改革開放.菅野よう子 - Main Theme～Piano.ape&lt;br /&gt;NHK.中國残留孤児.中島みゆき - ヘッドライト.テールライト.ape&lt;br /&gt;NHK.中國残留孤児.中島みゆき - 地上の星.ape&lt;br /&gt;NHK.加古隆 - 日米安保50年.mp3&lt;br /&gt;NHK.北漂一族　北京・さまよえる若者たち.张夏 - 你的眼睛.mp3&lt;br /&gt;NHK.四大文明.喜多郎 - 母なる大河.ape&lt;br /&gt;NHK.地球に乾杯.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.地球に乾杯.羽毛田丈史 - Theme(Pf Special Version) .mp3&lt;br /&gt;NHK.地球大進化　46億年・人類への旅.土井宏紀 - Opening.mp3&lt;br /&gt;NHK.地球白書.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.変革の世紀.坂本龍一 - Opening.mp3&lt;br /&gt;NHK.変革の世紀.坂本龍一 - Piano Solo.mp3&lt;br /&gt;NHK.大モンゴル.冨田勲 - 地獄からの使者.mp3&lt;br /&gt;NHK.大モンゴル.冨田勲 - 蒼き大地の記憶.mp3&lt;br /&gt;NHK.大モンゴル.冨田勲 - メインテーマ「蒼き狼」.mp3&lt;br /&gt;NHK.大河ドラマ「利家とまつ」.渡边俊幸 - 颯流.mp3&lt;br /&gt;NHK.大河ドラマ「毛利元就」.渡边俊幸 - メインテーマ.mp3&lt;br /&gt;NHK.チベット 天上の湖～标高5000メートルに生きる～.羽毛田丈史 - 天空の湖.mp3&lt;br /&gt;NHK.ドキュメント太平洋戦争.式部 - 漣歌.mp3&lt;br /&gt;NHK.失われた文明 インカ・マヤ.羽毛田丈史 - Main Theme.ape&lt;br /&gt;NHK.失われた文明 インカ・マヤ.羽毛田丈史 - 夜露(Opening Piano Solo).ape&lt;br /&gt;NHK.家族の肖像.ウォン ウィン ツァン - 運命と絆.mp3&lt;br /&gt;NHK.少年たち.渡边俊幸 - Main Theme.mp3&lt;br /&gt;NHK.悠久の長江，三峡.佐貫真希子 - 明日分の夢.mp3&lt;br /&gt;NHK.悠久の長江，三峡.岩代太郎 - 大河.mp3&lt;br /&gt;NHK.故宮~至宝が語る中華五千年~.S.E.N.S. - PALACE MEMORIES.mp3&lt;br /&gt;NHK.文明の道.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.新絲綢之路.马友友 - Distant Green Valley.mp3&lt;br /&gt;NHK.新絲綢之路.马友友 - Opening.mp3&lt;br /&gt;NHK.日本人はるかな旅.吉田潔 - TVオープニングテーマ.mp3&lt;br /&gt;NHK.日本人はるかな旅.吉田潔 - TVエンディングテーマ.mp3&lt;br /&gt;NHK.日本人はるかな旅.吉田潔 - 夢醒めて.mp3&lt;br /&gt;NHK.日本人はるかな旅.吉田潔 - 旅立ち.mp3&lt;br /&gt;NHK.日本の群像.再起への20年.加古隆 - Main Theme.mp3&lt;br /&gt;NHK.日本の、これから.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.映像の世紀.加古隆 - ワン.ワールド.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - ザ.サード.ワールド II.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - シネマトグラフ III.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - 時の刻印 II.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか ピアノ.ソロ.ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか ピアノ.トリオ.ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか ヴラス.ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか ジャズ.ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか オルガン.ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか オープニング.テーマ.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか オーケストラ.ショート_ヴァージョン.ape&lt;br /&gt;NHK.映像の世紀.加古隆 - パリは燃えているか -メインテーマ-.mp3&lt;br /&gt;NHK.映像の世紀.加古隆 - 睡蓮のアトリエ II.ape&lt;br /&gt;NHK.映像诗 里山～命めぐる水辺.羽毛田丈史 - 里山.mp3&lt;br /&gt;NHK.その時歴史が動いた.谷川賢作 - ピアノ・ヴァージョン.mp3&lt;br /&gt;NHK.その時歴史が動いた.谷川賢作 - エンディング・テーマ.mp3&lt;br /&gt;NHK.その時歴史が動いた.谷川賢作 - 憂愁.mp3&lt;br /&gt;NHK.その時歴史が動いた.谷川賢作 - 歓喜.mp3&lt;br /&gt;NHK.その時歴史が動いた.谷川賢作 - 黎明.mp3&lt;br /&gt;NHK.歴史秘话ヒストリア.梶浦由記 - Opening Theme.ape&lt;br /&gt;NHK.歴史秘话ヒストリア.梶浦由記 - Where My Story Begins.ape&lt;br /&gt;NHK.歴史秘话ヒストリア.梶浦由记 - Storia ～Instrumental～.mp3&lt;br /&gt;NHK.気候大异変.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.沸騰都市.川井憲次 - Ending.mp3&lt;br /&gt;NHK.沸騰都市.川井憲次 - Opening.mp3&lt;br /&gt;NHK.海上絲綢之路.S.E.N.S. - Amphora.ape&lt;br /&gt;NHK.海上絲綢之路.S.E.N.S. - Aphrodite.ape&lt;br /&gt;NHK.激流中國.五木田岳彦 - Opening.mp3&lt;br /&gt;NHK.生命 40億年はるかな旅.大島ミチル - Planet of Life~未知への贈り物~.mp3&lt;br /&gt;NHK.病の起源.羽毛田丈史 - Main Theme.mp3&lt;br /&gt;NHK.エジプト発掘.池頼広 - Opening.mp3&lt;br /&gt;NHK.社会主義の20世紀 - Opening.mp3&lt;br /&gt;NHK.よみがえる第二次世界大戦.川井憲次 - Apocalypse.mp3&lt;br /&gt;NHK.絲綢之路.喜多郎 - Main Theme.ape&lt;br /&gt;NHK.絲綢之路.喜多郎 - 丝路幻想.ape&lt;br /&gt;NHK.シリーズ マネー資本主義.細野晴臣 - Goodtime version.mp3&lt;br /&gt;NHK.シリーズ マネー資本主義.細野晴臣 - Opening version.mp3&lt;br /&gt;NHK.シリーズ マネー資本主義.細野晴臣 - Solo-Long version.mp3&lt;br /&gt;NHK.関口知宏の中國鉄道大紀行.大山百合香 - 光あるもの.ape&lt;br /&gt;NHK.関口知宏の中國鉄道大紀行.大山百合香 - 話さずにはいられない.mp3&lt;br /&gt;NHK.風林火山.千住明 - 風林火山 (燃ゆる日轮).ape&lt;br /&gt;NHK.驚異の小宇宙・人体III 遺伝子・DNA.久石譲 - Gene.mp3&lt;br /&gt;NHK.驚異の小宇宙・人体II 脳と心.久石譲 - BRAIN&amp;MIND 未知の秘境へのいざない.mp3&lt;br /&gt;NHK.驚異の小宇宙・人体.久石譲.THE INNERS ~遙かなる時間の彼方へ.mp3&lt;br /&gt;Nicolas De Angelis - Quelques Notes Pour Anna.ape&lt;br /&gt;Once Upon A Time In America.Ennio Morricone - Childhood Memories.ape&lt;br /&gt;Once Upon A Time In America.Ennio Morricone - Cockeye's Song.ape&lt;br /&gt;Once Upon A Time In America.Ennio Morricone - Main Theme.ape&lt;br /&gt;Once Upon A Time In The West.Ennio Morricone - Main Theme.ape&lt;br /&gt;Reservoir Dogs.Joe Tex - I Gotcha.ape&lt;br /&gt;Richard Clayderman - A Comme Amour.ape&lt;br /&gt;Richard Clayderman - Aline.ape&lt;br /&gt;Richard Clayderman - Amour Pour Amour.ape&lt;br /&gt;Richard Clayderman - Andeline A Grandi.ape&lt;br /&gt;Richard Clayderman - Ballade Pour Adeline.ape&lt;br /&gt;Richard Clayderman - Can You Feel The Love Tonight.ape&lt;br /&gt;Richard Clayderman - Coeur Fragile.ape&lt;br /&gt;Richard Clayderman - Concerto Pour Unr Jeune Fille Nommee Je Taime.ape&lt;br /&gt;Richard Clayderman - Couleur Tendresse.ape&lt;br /&gt;Richard Clayderman - Dolannes Melody.ape&lt;br /&gt;Richard Clayderman - Ecoute Omon Amour.ape&lt;br /&gt;Richard Clayderman - Eleana.ape&lt;br /&gt;Richard Clayderman - Eroica.ape&lt;br /&gt;Richard Clayderman - Feelings.ape&lt;br /&gt;Richard Clayderman - Finlandia.ape&lt;br /&gt;Richard Clayderman - Flower Heart.ape&lt;br /&gt;Richard Clayderman - Four Seasons Spring.ape&lt;br /&gt;Richard Clayderman - Fur Elise.ape&lt;br /&gt;Richard Clayderman - Greensleeves.ape&lt;br /&gt;Richard Clayderman - Kampai.ape&lt;br /&gt;Richard Clayderman - Lady Di.ape&lt;br /&gt;Richard Clayderman - Les Colombes Du Tenere.ape&lt;br /&gt;Richard Clayderman - Les Premiers Sourires de Vanessa.ape&lt;br /&gt;Richard Clayderman - Lettre A Ma Mere.ape&lt;br /&gt;Richard Clayderman - L’ocean.ape&lt;br /&gt;Richard Clayderman - Love is Blue.ape&lt;br /&gt;Richard Clayderman - Love Story.ape&lt;br /&gt;Richard Clayderman - Marriage d'Amour.ape&lt;br /&gt;Richard Clayderman - Marriage D'amour.ape&lt;br /&gt;Richard Clayderman - Melody.ape&lt;br /&gt;Richard Clayderman - Moon River.ape&lt;br /&gt;Richard Clayderman - MurMures.ape&lt;br /&gt;Richard Clayderman - Nocturne.ape&lt;br /&gt;Richard Clayderman - Pour Elise.ape&lt;br /&gt;Richard Clayderman - Premiers Sourires de Vanessa.ape&lt;br /&gt;Richard Clayderman - Romeo And Juliet.ape&lt;br /&gt;Richard Clayderman - Souvenirs D'enfance.ape&lt;br /&gt;Richard Clayderman - Triste Coeur.ape&lt;br /&gt;Richard Clayderman - Voyage Of Venice.ape&lt;br /&gt;Richard Marx - Right Here Waiting.ape&lt;br /&gt;S.E.N.S - Edge of the Storm.ape&lt;br /&gt;Sonatine.久石譲 - See You....ape&lt;br /&gt;Sonatine.久石譲 - Sonatine 1 (Act of Violence).ape&lt;br /&gt;Stanley Myers - Cavatina.ape&lt;br /&gt;Taegukgi - My Brother.ape&lt;br /&gt;Taegukgi - Prologue.ape&lt;br /&gt;Tap Dance - River Dance.ape&lt;br /&gt;Teresa Perez - Fantasia On Greensleeves.ape&lt;br /&gt;TheDon Davis - The Matrix II.ape&lt;br /&gt;The English Patient.Gabriel Yared - As far as Florence.ape&lt;br /&gt;The English Patient.Gabriel Yared - Main Theme.ape&lt;br /&gt;The Godfather - Love Theme.ape&lt;br /&gt;The Good, the Bad and the Ugly.Ennio Morricone - Main Theme.ape&lt;br /&gt;The Good, the Bad and the Ugly.Ennio Morricone - The Ecstasy of Gold.mp3&lt;br /&gt;The Lion King.Elton John - Can You Feel The Love Tonight (End Credits).ape&lt;br /&gt;The Lion King.Elton John - Circle Of Life 2.ape&lt;br /&gt;The Lion King.Elton John - Circle Of Life.ape&lt;br /&gt;The Lion King.Elton John - I Just Can't Wait To Be King.ape&lt;br /&gt;The Lion King.Hans Zimmer - Be Prepared.ape&lt;br /&gt;The Lion King.Hans Zimmer - Can You Feel The Love Tonight.ape&lt;br /&gt;The Lion King.Hans Zimmer - Hakuna Matata.ape&lt;br /&gt;Trademark - Only love.ape&lt;br /&gt;Vangelis - 1492 Conquest of Paradise (End Titles).ape&lt;br /&gt;Vivaldi - Four Seasons 'Spring'.ape&lt;br /&gt;Whitney Houston - I Will Always Love You.ape&lt;br /&gt;Whitney Houston - One Moment In Time.ape&lt;br /&gt;中島みゆき - 幸せ.ape&lt;br /&gt;久石譲 - Act 1 _ 02-W Nocturne.ape&lt;br /&gt;久石譲 - Asian Dream Song.ape&lt;br /&gt;久石譲 - il porco rosso.ape&lt;br /&gt;久石譲 - Innocent.ape&lt;br /&gt;久石譲 - 少女のままで.ape&lt;br /&gt;井上あずみ - おかあさん.ape&lt;br /&gt;加古隆 - 大河の一滴.mp3&lt;br /&gt;千昌夫 - 北國の春.ape&lt;br /&gt;古筝 - 出水莲.ape&lt;br /&gt;古筝 - 知音.ape&lt;br /&gt;古筝 - 高山流水.ape&lt;br /&gt;叶加瀬太郎 - 流転の王妃・最後の皇弟 メインテーマ.mp3&lt;br /&gt;周璇名曲 - 叮咛.ape&lt;br /&gt;周璇名曲 - 夜上海.ape&lt;br /&gt;周璇名曲 - 莫忘今宵.ape&lt;br /&gt;周璇名曲 - 麻雀经.ape&lt;br /&gt;夏川里美 - 童神～ヤマトグチ～.ape&lt;br /&gt;かぐや姫 - 神田川.mp3&lt;br /&gt;小提琴 - 梁祝.ape&lt;br /&gt;山口百惠 - さよならの向う側.ape&lt;br /&gt;山口百惠 - 山鸠.ape&lt;br /&gt;山口百惠 - 惜春（せきしゅん）通り.ape&lt;br /&gt;山口百惠 - 愛染橋（あいぜんばし）.ape&lt;br /&gt;山口百惠 - いい日旅立ち.ape&lt;br /&gt;山口百惠 - 爱ジョ走ジ.ape&lt;br /&gt;山口百惠 - 秋桜（コスモス）.ape&lt;br /&gt;山口百惠 - ありがとうあなた（《血疑》主题曲）.ape&lt;br /&gt;岡本眞夜 - TOMORROW.ape&lt;br /&gt;座頭市.Keiichi Suzuki - Festivo.ape&lt;br /&gt;座頭市.Keiichi Suzuki - Road to a Post-Town.ape&lt;br /&gt;日経スペシャル ガイアの夜明け.岸利至新井誠志羽毛田丈史後藤勇一郎 - ガイアの夜明け～鼓動～.mp3&lt;br /&gt;日経スペシャル ガイアの夜明け.岸利至新井誠志羽毛田丈史後藤勇一郎 - 鼓動～Gate Of Awakening～.mp3&lt;br /&gt;木村好夫 - 濑柳小镇.ape&lt;br /&gt;松谷卓 - 匠.mp3&lt;br /&gt;玉置浩二 - 李香兰.ape&lt;br /&gt;美空ひばり - 川の流れのように.mp3&lt;br /&gt;羽毛田丈史 - A Song for the Sprout.mp3&lt;br /&gt;羽毛田丈史 - Blue Waltz.mp3&lt;br /&gt;羽毛田丈史 - Elegant Calm of the Moment.mp3&lt;br /&gt;羽毛田丈史 - Impromptu～風·水·光.mp3&lt;br /&gt;羽毛田丈史 - Jazz Largo.mp3&lt;br /&gt;羽毛田丈史 - Joyful Air Line ～live image prologue～.mp3&lt;br /&gt;羽毛田丈史 - Leaf of Agastya.mp3&lt;br /&gt;羽毛田丈史 - オーマイ・ガール.mp3&lt;br /&gt;羽毛田丈史 - ROOKIES ~爱のテーマ~.mp3&lt;br /&gt;羽毛田丈史 - Train to Dream.mp3&lt;br /&gt;羽毛田丈史 - 夏の记忆 ~Remembrance~.mp3&lt;br /&gt;羽毛田丈史 - 彗星物语.mp3&lt;br /&gt;羽毛田丈史 - 恋せども、爱せども.mp3&lt;br /&gt;羽毛田丈史 - この空と大地の出会う場所.mp3&lt;br /&gt;羽毛田丈史 - もし 翼があったなら.mp3&lt;br /&gt;羽毛田丈史 - 青の翳り.mp3&lt;br /&gt;羽毛田丈史 - 黄昏のビギン.mp3&lt;br /&gt;芹洋子 - 四季の歌.mp3&lt;br /&gt;菊次郎の夏.久石譲 - Going Out.ape&lt;br /&gt;菊次郎の夏.久石譲 - Kindness.ape&lt;br /&gt;菊次郎の夏.久石譲 - Summer.ape&lt;br /&gt;菊次郎の夏.久石譲 - The Rain.ape&lt;br /&gt;邓丽君 - 时の流れに身.mp3&lt;br /&gt;鄧麗君 - 冬のひまわり.ape&lt;br /&gt;鄧麗君 - 別れの予感.ape&lt;br /&gt;鄧麗君 - 恋人たちの神話.ape&lt;br /&gt;鄧麗君 - 悲しみと踊らせて.ape&lt;br /&gt;鄧麗君 - 時の流れに身をまかせ.ape&lt;br /&gt;鄧麗君 - ジェルソミーナの歩いた道.ape&lt;br /&gt;鄧麗君 - 空港.ape&lt;br /&gt;酒井法子 - 世界中の誰よりきっと.ape&lt;br /&gt;酒井法子 - 碧いうさぎ.ape&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-8141902608297588468?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/8141902608297588468/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/03/music_31.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/8141902608297588468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/8141902608297588468'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/03/music_31.html' title='music'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-5374304173409639345</id><published>2010-03-31T19:25:00.001+08:00</published><updated>2010-03-31T19:25:22.908+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux install'/><title type='text'>grub and boot</title><content type='html'>&lt;pre&gt;&lt;br /&gt;好久没装xp了，以前装过双系统，现在就一个fedora8，编译过kernel 2.6.31。虽然没装xp，但不影响介绍&lt;br /&gt;引导原理。这里先学会修复xp+linux双系统启动的几个问题，然后从实用角度介绍Linux启动过程。&lt;br /&gt;先了解一些常识：&lt;br /&gt;&lt;br /&gt;filesystem必须被mount上才能使用，一个partition上有一个fs&lt;br /&gt;root filesystem: 系统启动后第一个被mount的文件系统，其它fs必须在root fs的基础上才能被mount。&lt;br /&gt;root device: root fs所依附的存储介质，可选项很多: 硬盘, 光盘, RAID, USB，硬盘的某个分区...&lt;br /&gt;kernel启动时会逐步尝试找root device: ata, scsi, RAID, USB，root=/dev/X...&lt;br /&gt;&lt;br /&gt;root directory: 每个partition最顶级的目录，每个partition一个&lt;br /&gt;root partition: root directory 所在的partition&lt;br /&gt;&lt;br /&gt;比如 info grub中介绍grub-install命令时就用到了，当然grub-install命令容易出错，最好别用:&lt;br /&gt;&lt;br /&gt;   But all the above examples assume that GRUB should use images under&lt;br /&gt;the root directory. If you want GRUB to use images under a directory&lt;br /&gt;other than the root directory, you need to specify the option&lt;br /&gt;`--root-directory'. The typical usage is that you create a GRUB boot&lt;br /&gt;floppy with a filesystem. Here is an example:&lt;br /&gt;&lt;br /&gt;     # mke2fs /dev/fd0&lt;br /&gt;     # mount -t ext2 /dev/fd0 /mnt&lt;br /&gt;     # grub-install --root-directory=/mnt fd0&lt;br /&gt;     # umount /mnt&lt;br /&gt;&lt;br /&gt;   Another example is when you have a separate boot partition which is&lt;br /&gt;mounted at `/boot'. Since GRUB is a boot loader, it doesn't know&lt;br /&gt;anything about mountpoints at all. Thus, you need to run `grub-install'&lt;br /&gt;like this:&lt;br /&gt;     # grub-install --root-directory=/boot /dev/hda&lt;br /&gt;&lt;br /&gt;每个partition都有一个superblock，dumpe2fs /dev/sda5 看到很多sb都是第一个sb的备份&lt;br /&gt;注意 /root 不是root directory，它只是root用户的 home dir&lt;br /&gt;&lt;br /&gt;对于sata和scsi接口的硬盘:&lt;br /&gt;第一Master：/dev/sda   第一Slave：/dev/sdb  第二Master：/dev/sdc   第二Slave：/dev/sdd&lt;br /&gt;xp下多个硬盘时是顺序分配盘符，而linux这种表示方法是能区分每一块硬盘的。&lt;br /&gt;&lt;br /&gt;MBR是整个硬盘的第一个sector，包括446B的bootstrap program，64B分区表，2B的signature。&lt;br /&gt;boot sector是某个partition的第一个sector，因此MBR是一个特殊的boot sector。&lt;br /&gt;&lt;br /&gt;win下对应grub的引导程序叫ntldr。grub分stage1和stage2两个部分，有的系统的引导程序还有个1.5，&lt;br /&gt;都在/boot/grub/下，stage2有配置文件/etc/grub.conf，linux启动文件都在 /boot/ 下，&lt;br /&gt;&lt;br /&gt;[cngrid@cn122 ~]$ ll /boot&lt;br /&gt;total 15939&lt;br /&gt;-rw-r--r--. 1 root root   103788 2009-11-08 10:38 config-2.6.31.5-127.fc12.i686.PAE&lt;br /&gt;drwxr-xr-x. 3 root root     1024 2010-03-30 18:12 efi&lt;br /&gt;drwxr-xr-x. 2 root root     1024 2010-03-30 18:36 grub&lt;br /&gt;-rw-r--r--. 1 root root 11252942 2010-03-30 18:26 initramfs-2.6.31.5-127.fc12.i686.PAE.img&lt;br /&gt;drwx------. 2 root root    12288 2010-03-30 17:51 lost+found&lt;br /&gt;-rw-r--r--. 1 root root  1486532 2009-11-08 10:38 System.map-2.6.31.5-127.fc12.i686.PAE&lt;br /&gt;-rwxr-xr-x. 1 root root  3454368 2009-11-08 10:38 vmlinuz-2.6.31.5-127.fc12.i686.PAE&lt;br /&gt;&lt;br /&gt;注意vmlinuz就是stage2要load的kernel。&lt;br /&gt;&lt;br /&gt;[cngrid@cn122 ~]$ ls -l /boot/grub&lt;br /&gt;total 305&lt;br /&gt;-rw-r--r--. 1 root root     63 2010-03-30 18:36 device.map&lt;br /&gt;-rw-r--r--. 1 root root  14872 2010-03-30 18:36 e2fs_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  14036 2010-03-30 18:36 fat_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  13344 2010-03-30 18:36 ffs_stage1_5&lt;br /&gt;-rw-------. 1 root root    728 2010-03-30 18:36 grub.conf&lt;br /&gt;-rw-r--r--. 1 root root  13356 2010-03-30 18:36 iso9660_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  14928 2010-03-30 18:36 jfs_stage1_5&lt;br /&gt;lrwxrwxrwx. 1 root root     11 2010-03-30 18:36 menu.lst -&amp;gt; ./grub.conf&lt;br /&gt;-rw-r--r--. 1 root root  13480 2010-03-30 18:36 minix_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  16128 2010-03-30 18:36 reiserfs_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  17488 2009-10-02 00:08 splash.xpm.gz&lt;br /&gt;-rw-r--r--. 1 root root    512 2010-03-30 18:36 stage1&lt;br /&gt;-rw-r--r--. 1 root root 125432 2010-03-30 18:36 stage2&lt;br /&gt;-rw-r--r--. 1 root root  13628 2010-03-30 18:36 ufs2_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  12932 2010-03-30 18:36 vstafs_stage1_5&lt;br /&gt;-rw-r--r--. 1 root root  15664 2010-03-30 18:36 xfs_stage1_5&lt;br /&gt;&lt;br /&gt;[cngrid@cn122 ~]$ sudo cat /etc/grub.conf&lt;br /&gt;# grub.conf generated by anaconda&lt;br /&gt;#&lt;br /&gt;# Note that you do not have to rerun grub after making changes to this file&lt;br /&gt;# NOTICE:  You have a /boot partition.  This means that&lt;br /&gt;#          all kernel and initrd paths are relative to /boot/, eg.&lt;br /&gt;#          root (hd0,0)&lt;br /&gt;#          kernel /vmlinuz-version ro root=/dev/sda2&lt;br /&gt;#          initrd /initrd-[generic-]version.img&lt;br /&gt;#boot=/dev/sda&lt;br /&gt;default=0&lt;br /&gt;timeout=0&lt;br /&gt;splashimage=(hd0,0)/grub/splash.xpm.gz&lt;br /&gt;hiddenmenu&lt;br /&gt;title Fedora (2.6.31.5-127.fc12.i686.PAE)&lt;br /&gt; root (hd0,0)&lt;br /&gt; kernel /vmlinuz-2.6.31.5-127.fc12.i686.PAE ro root=UUID=bf2509ce-dd51-4760-8e9f-3b7cdb7d79b5  LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rhgb quiet&lt;br /&gt; initrd /initramfs-2.6.31.5-127.fc12.i686.PAE.img&lt;br /&gt;&lt;br /&gt;注释是说/boot分区的，另一台机器只有一个 / 分区，对比两台机器的grub.conf就明白了：&lt;br /&gt;&lt;br /&gt;[root@gridserver ~]# cat /etc/grub.conf&lt;br /&gt;# grub.conf generated by anaconda&lt;br /&gt;#&lt;br /&gt;# Note that you do not have to rerun grub after making changes to this file&lt;br /&gt;# NOTICE:  You do not have a /boot partition.  This means that&lt;br /&gt;#          all kernel and initrd paths are relative to /, eg.&lt;br /&gt;#          root (hd0,0)&lt;br /&gt;#          kernel /boot/vmlinuz-version ro root=/dev/sda1&lt;br /&gt;#          initrd /boot/initrd-version.img&lt;br /&gt;#boot=/dev/sda&lt;br /&gt;default=0&lt;br /&gt;timeout=5&lt;br /&gt;splashimage=(hd0,0)/boot/grub/splash.xpm.gz&lt;br /&gt;hiddenmenu&lt;br /&gt;title Red Hat Enterprise Linux AS (2.6.9-22.ELsmp)&lt;br /&gt;        root (hd0,0)&lt;br /&gt;        kernel /boot/vmlinuz-2.6.9-22.ELsmp ro root=LABEL=/ rhgb quiet&lt;br /&gt;        initrd /boot/initrd-2.6.9-22.ELsmp.img&lt;br /&gt;&lt;br /&gt;关键就下面三行:&lt;br /&gt;#          root (hd0,0)&lt;br /&gt;#          kernel /vmlinuz-version ro root=/dev/sda2&lt;br /&gt;#          initrd /initrd-version.img&lt;br /&gt;&lt;br /&gt;第一行是说root device的位置在 (hd0,0)，stage1, stage2, kernel image和initrd都在那。&lt;br /&gt;一般grub就在硬盘上，所以后面跟的是一个硬盘分区。如果把grub装在了cd上，就 root (cd)，&lt;br /&gt;&lt;br /&gt;第二行是kernel image name, 后面的 root=/dev/sda2 才是真正在说root device: 视/dev/sda2为&lt;br /&gt;root device，kernel将来就用这个root device上的filesystem作为root fs。&lt;br /&gt;# df -h 能看到 /dev/sda2 就是 / 分区。而grub指定的那个"root"是指 /boot 分区。&lt;br /&gt;[cngrid@cn122 ~]$ df -h&lt;br /&gt;Filesystem            Size  Used Avail Use% Mounted on&lt;br /&gt;/dev/sda2             9.7G  438M  8.7G   5% /&lt;br /&gt;tmpfs                 499M  420K  498M   1% /dev/shm&lt;br /&gt;/dev/sda1             146M   22M  117M  16% /boot&lt;br /&gt;/dev/sda3              39G   28G  9.2G  76% /home&lt;br /&gt;/dev/sda5              24G   17G  6.4G  72% /usr&lt;br /&gt;//10.0.1.15/共享    108G  100G  7.6G  94% /mnt/win&lt;br /&gt;&lt;br /&gt;从这也看出: 如果没有单独划分/boot分区，则这两个root就相同了，更容易混淆了。&lt;br /&gt;&lt;br /&gt;这里自己可以加参数，比如忘记root密码，grub图形时e 然后在 kernel /vmlinuz 这行加上 single，&lt;br /&gt;就可以单用户进入系统，passwd root改密码了。rhgb quiet也是参数，还有更多。&lt;br /&gt;&lt;br /&gt;1。config-2.6.31.5-127.fc12.i686.PAE&lt;br /&gt;   内核编译选项。想知道系统是否preemptible就grep PREEMPT config-2.6.31.5-127.fc12.i686.PAE&lt;br /&gt;2。System.map-2.6.31.5-127.fc12.i686.PAE 是kernel的符号表，man nm&lt;br /&gt;3。initramfs-2.6.31.5-127.fc12.i686.PAE.img 是系统启动时帮助mount root fs的，是一个基于内存&lt;br /&gt;   的文件系统。这样解压:&lt;br /&gt;&lt;br /&gt;# file initramfs-2.6.31.5-127.fc12.i686.PAE.img&lt;br /&gt;initramfs-2.6.31.5-127.fc12.i686.PAE.img: gzip compressed data, from Unix, last modified:&lt;br /&gt;Tue Mar 30 18:25:50 2010, max compression&lt;br /&gt;&lt;br /&gt;# mv initramfs-2.6.31.5-127.fc12.i686.PAE.img initrd-2.6.31.gz&lt;br /&gt;# gunzip initrd-2.6.31.gz&lt;br /&gt;# cpio -id &amp;lt; initrd-2.6.31&lt;br /&gt;&lt;br /&gt;linux启动时先mount了一个叫rootfs的内存文件系统，cat /proc/mounts 可以看到，rootfs不能被umount。&lt;br /&gt;在此基础上进一步mount基于存储介质的root fs。&lt;br /&gt;&lt;br /&gt;为什么需要initrd.img呢?编译kernel时在硬盘驱动那里容易kernel panic:&lt;br /&gt;因为编译kernel时ext3和一些scsi，ata的硬盘驱动默认是m，并没有编译到kernel中来。这样当kernel启动&lt;br /&gt;阶段需要scsi, ata这些硬盘的驱动时，由于驱动没编译进kernel中，就现找，而所需的驱动模块却又在硬盘&lt;br /&gt;上，自然是找不到。initrd就是来解决这个问题的，它里面有一些基本文件系统如ext3和硬盘的驱动模块，&lt;br /&gt;系统启动时grub把initrd完全load到内存里，等kernel启动时就不会再到硬盘上找驱动模块了。&lt;br /&gt;&lt;br /&gt;当然，如果在make menuconfig时把ext3等硬盘驱动的选项由m改成y就不用initrd了，关键是选多了会使&lt;br /&gt;kernel臃肿，选少了又会kernel panic，所以一般都用initrd做帮助，而且目标是将来把驱动全放这个&lt;br /&gt;initrd里，这样kernel就会变的精简。&lt;br /&gt;&lt;br /&gt;initrd是一个基于内存的root fs，用来帮助kernel mount我们平时说的root fs，而对一些没有非易失性介&lt;br /&gt;质的嵌入式系统，initrd就是系统最终的root fs。&lt;br /&gt;&lt;br /&gt;看看源码:&lt;br /&gt;kernel_init()-&amp;gt; prepare_namespace():&lt;br /&gt;/*&lt;br /&gt; * Prepare the namespace - decide what/where to mount, load ramdisks, etc.&lt;br /&gt; */&lt;br /&gt;void __init prepare_namespace(void)&lt;br /&gt;{&lt;br /&gt;        int is_floppy;&lt;br /&gt;&lt;br /&gt;        if (root_delay) {&lt;br /&gt;                printk(KERN_INFO "Waiting %dsec before mounting root device...\n",&lt;br /&gt;                       root_delay);&lt;br /&gt;                ssleep(root_delay);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /*&lt;br /&gt;         * wait for the known devices to complete their probing&lt;br /&gt;         *&lt;br /&gt;         * Note: this is a potential source of long boot delays.&lt;br /&gt;         * For example, it is not atypical to wait 5 seconds here&lt;br /&gt;         * for the touchpad of a laptop to initialize.&lt;br /&gt;         */&lt;br /&gt;        wait_for_device_probe();&lt;br /&gt;&lt;br /&gt;        md_run_setup();        &lt;br /&gt;&lt;br /&gt;        if (saved_root_name[0]) {&lt;br /&gt;                root_device_name = saved_root_name;&lt;br /&gt;                if (!strncmp(root_device_name, "mtd", 3) ||     // RAID&lt;br /&gt;                    !strncmp(root_device_name, "ubi", 3)) {     // USB&lt;br /&gt;                        mount_block_root(root_device_name, root_mountflags);&lt;br /&gt;                        goto out;&lt;br /&gt;                }&lt;br /&gt;                ROOT_DEV = name_to_dev_t(root_device_name);     &lt;br /&gt;                if (strncmp(root_device_name, "/dev/", 5) == 0) // grub root=/dev/X &lt;br /&gt;                        root_device_name += 5;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (initrd_load())   &lt;br /&gt;                goto out;&lt;br /&gt;&lt;br /&gt;        /* wait for any asynchronous scanning to complete */&lt;br /&gt;        if ((ROOT_DEV == 0) &amp;&amp; root_wait) {&lt;br /&gt;                printk(KERN_INFO "Waiting for root device %s...\n",&lt;br /&gt;                        saved_root_name);&lt;br /&gt;                while (driver_probe_done() != 0 ||&lt;br /&gt;                        (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)&lt;br /&gt;                        msleep(100);&lt;br /&gt;                async_synchronize_full();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;&lt;br /&gt;&lt;br /&gt;        if (is_floppy &amp;&amp; rd_doload &amp;&amp; rd_load_disk(0)) &lt;br /&gt;                ROOT_DEV = Root_RAM0;&lt;br /&gt;&lt;br /&gt;        mount_root();     &lt;br /&gt;out:&lt;br /&gt;        sys_mount(".", "/", NULL, MS_MOVE, NULL);    // mount root fs &lt;br /&gt;        sys_chroot(".");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;先是Wating一段时间让用户准备root device;&lt;br /&gt;对RAID USB进行探测，要探测成功还要在mount_block_root()中对各种文件系统类型ext2/ext3/等逐个试验，&lt;br /&gt;然后调用sys_mount()来mount root fs，此时不用initrd。&lt;br /&gt;看一下mount_block_root()，其中的很多printk有助于我们将来排错:&lt;br /&gt;&lt;br /&gt;void __init mount_block_root(char *name, int flags)&lt;br /&gt;{&lt;br /&gt;        char *fs_names = __getname_gfp(GFP_KERNEL&lt;br /&gt;                | __GFP_NOTRACK_FALSE_POSITIVE);&lt;br /&gt;        char *p;&lt;br /&gt;#ifdef CONFIG_BLOCK&lt;br /&gt;        char b[BDEVNAME_SIZE];&lt;br /&gt;#else&lt;br /&gt;        const char *b = name;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;        get_fs_names(fs_names);&lt;br /&gt;retry:&lt;br /&gt;        for (p = fs_names; *p; p += strlen(p)+1) {     // test filesystem type one by one&lt;br /&gt;                int err = do_mount_root(name, p, flags, root_mount_data);&lt;br /&gt;                switch (err) {&lt;br /&gt;                        case 0:&lt;br /&gt;                                goto out;&lt;br /&gt;                        case -EACCES:&lt;br /&gt;                                flags |= MS_RDONLY;&lt;br /&gt;                                goto retry;&lt;br /&gt;                        case -EINVAL:&lt;br /&gt;                                continue;&lt;br /&gt;                }&lt;br /&gt;                /*&lt;br /&gt;                 * Allow the user to distinguish between failed sys_open&lt;br /&gt;                 * and bad superblock on root device.&lt;br /&gt;                 * and give them a list of the available devices&lt;br /&gt;                 */&lt;br /&gt;#ifdef CONFIG_BLOCK&lt;br /&gt;                __bdevname(ROOT_DEV, b);&lt;br /&gt;#endif&lt;br /&gt;                printk("VFS: Cannot open root device \"%s\" or %s\n",&lt;br /&gt;                                root_device_name, b);&lt;br /&gt;                printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");&lt;br /&gt;&lt;br /&gt;                printk_all_partitions();&lt;br /&gt;#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT&lt;br /&gt;                printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "&lt;br /&gt;                       "explicit textual name for \"root=\" boot option.\n");&lt;br /&gt;#endif&lt;br /&gt;                panic("VFS: Unable to mount root fs on %s", b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        printk("List of all partitions:\n");&lt;br /&gt;        printk_all_partitions();&lt;br /&gt;        printk("No filesystem could mount root, tried: ");&lt;br /&gt;        for (p = fs_names; *p; p += strlen(p)+1)&lt;br /&gt;                printk(" %s", p);&lt;br /&gt;        printk("\n");&lt;br /&gt;#ifdef CONFIG_BLOCK&lt;br /&gt;        __bdevname(ROOT_DEV, b);&lt;br /&gt;#endif&lt;br /&gt;        panic("VFS: Unable to mount root fs on %s", b);&lt;br /&gt;out:&lt;br /&gt;        putname(fs_names);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;若没成功就继续尝试本地硬盘，这是最常见的情况。由grub传的参数/dev/X得出device number，&lt;br /&gt;然后把initrd文件load进内存，然后再mount root fs。如果硬盘也不成功就尝试floppy。&lt;br /&gt;mount root fs之后，就 execve /sbin/init生成init进程，init进程会重新mount root fs为rw。&lt;br /&gt;&lt;br /&gt;知道这些就会定制Linux的启动过程了，比如有了一种新硬件，完全可以做好驱动，把root fs放在新硬件上，&lt;br /&gt;然后更改kernel源码就行了; 也可以把grub备份在u盘上; 在LAN中把vmlinuz文件放在网络上，进行网络安装。&lt;br /&gt;&lt;br /&gt;硬盘安装的例子，在fedora 8上硬盘装fedora 12:&lt;br /&gt;&lt;br /&gt;把iso放在一个安装过程中不会被破坏的分区中，假设在/home/cngrid/f12/下&lt;br /&gt;把iso中的 initrd.img 和 vmlinuz copy到/boot/下，可以改名，修改grub，成为:&lt;br /&gt;/boot/initrd-f12.img&lt;br /&gt;/boot/vmlinuz-f12&lt;br /&gt;&lt;br /&gt;要求iso和iso中的images都在一个文件夹下，即&lt;br /&gt;/home/cngrid/f12/Fedora-12-i386-DVD.iso&lt;br /&gt;/home/cngrid/f12/images&lt;br /&gt;&lt;br /&gt;命令是:&lt;br /&gt;# mount -t iso9660 /home/cngrid/fedora/Fedora-12-i386-DVD.iso /mnt/f12/ -o loop&lt;br /&gt;# cp /mnt/f12/isolinux/initrd /boot/initrd-fedora.12.img&lt;br /&gt;# cp /mnt/f12/isolinux/vmlinuz /boot/vmlinuz-fedora.12&lt;br /&gt;# cp -r /mnt/f12/images/ /home/cngrid/f12/&lt;br /&gt;# umount /mnt/f12/&lt;br /&gt;# vi /etc/grub.conf  末尾添加启动项&lt;br /&gt;title Fedora 12                                          &lt;br /&gt; root (hd0,0)&lt;br /&gt; kernel /vmlinuz-f12 ro root=LABEL=/ rhgb quiet&lt;br /&gt; initrd /initrd-f12.img&lt;br /&gt;&lt;br /&gt;df -h 记住iso所在分区，一会要用。重启，title Fedora 12 -&amp;gt; Hard Drive -&amp;gt; /dev/sda2 -&amp;gt; &lt;br /&gt;Directory holding images: 不用填能自动搜索到iso, 继续就和光盘安装一样了。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-5374304173409639345?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/5374304173409639345/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/03/grub-and-boot_31.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5374304173409639345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5374304173409639345'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/03/grub-and-boot_31.html' title='grub and boot'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-4908483760498865763</id><published>2010-03-31T19:18:00.091+08:00</published><updated>2011-10-22T17:52:48.868+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux install'/><title type='text'>linuxer</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    处理视频，Windows 下有很多图形界面的工具，由于涉及到视频、音频、字幕...参数太多，图形界面太&lt;br /&gt;复杂，想告诉别人处理过程还得截图，此时 Linux commandline 的优势出来了，用起来比图形界面简单易懂。&lt;br /&gt;&lt;br /&gt;    区分 video format 和 codec。avi mkv mp4 都属于format，被称为container，里面包含video、audio、&lt;br /&gt;sub，对应有 vcodec、acodec、scodec。&lt;br /&gt;    &lt;br /&gt;    Windows 为了方便普通用户，把文件的扩展名用类似 format 的名字来表示，有的就是 format 名字本身。&lt;br /&gt;因此Windows下想知道视频的format就看扩展名:&lt;br /&gt;    .avi .mp4 .rm .vob 和其format名相同&lt;br /&gt;    .mpg format名是 mpeg&lt;br /&gt;    .mkv format名是 matroska&lt;br /&gt;&lt;br /&gt;    当然用扩展名也有坏处，比如一个a.rar可能无法解压，因为这个a.rar是由一个电脑新手把a.txt直接改&lt;br /&gt;名成a.rar的；或者下了一个.torrent无法下载，实际是制作人把.torrent压缩成了zip，然后又改名成.torrent。&lt;br /&gt;Linux 下就没这类问题，解压不了就用file命令看一下真正的format，然后用相应的工具处理。把foo.avi改名&lt;br /&gt;为foo，也照样能用 $ mplayer foo 播放。&lt;br /&gt;&lt;br /&gt;    通常文件扩展名就代表文件的format，但由于用户可以任意修改扩展名，所以拿来一个新文件，无法确&lt;br /&gt;定a.avi 就是 avi format，普通用户在这里会被误导。&lt;br /&gt;&lt;br /&gt;    这里也看出来 Windows 那一套机制都是给傻瓜用户用的，方便却糊里糊涂；Linux 是给大学生用的，不&lt;br /&gt;方便但是有利于培养思考能力。有些国家连计算机系的大学生都普及 Windows，就可以知道这个国家没有原&lt;br /&gt;创技术，也不崇尚创新，大学都是衙门，不是培养人才之地。&lt;br /&gt;&lt;br /&gt;    查看 format 和 codec:&lt;br /&gt;    $ ffmpeg -formats|less&lt;br /&gt;    $ ffmpeg -codecs|less&lt;br /&gt;&lt;br /&gt;file 命令看 format 和 codec:&lt;br /&gt;$ file * &lt;br /&gt;foo.DAT:              RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;foo.mpg:              RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;foo.vob:              MPEG sequence, v2, program multiplex&lt;br /&gt;foo.wmv:              Microsoft ASF&lt;br /&gt;foo.asf:              Microsoft ASF&lt;br /&gt;foo.rm:               RealMedia file&lt;br /&gt;foo.mkv:              Matroska data&lt;br /&gt;foo.mp4:              ISO Media, MPEG v4 system, version 1&lt;br /&gt;foo.m4v:              ISO Media, MPEG v4 system, iTunes AVC-LC&lt;br /&gt;foo.mov:              ISO Media, Apple QuickTime movie&lt;br /&gt;foo.flv:              Macromedia Flash Video&lt;br /&gt;foo.ts:               MPEG transport stream data&lt;br /&gt;foo.avi:              RIFF (little-endian) data, AVI, 640 x 480, 25.00 fps, video: XviD, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)&lt;br /&gt;foo1.avi:             RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: H.264 X.264 or H.264, audio: MPEG-1 Layer 3 (stereo, 22050 Hz)&lt;br /&gt;foo2.avi:             RIFF (little-endian) data, AVI, 352 x 256, 30.00 fps, video: DivX 5, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)&lt;br /&gt;foo3.avi:             RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: Motion JPEG, audio: uLaw (mono, 8000 Hz)&lt;br /&gt;&lt;br /&gt;    常见 format: avi mkv mp4 vob mpg mov wmv rm ...&lt;br /&gt;    常见 vcodec: MPEG-1 MPEG-2 MPEG-4 H.264 wmv3 RV40...&lt;br /&gt;    常见 acodec: AAC ac3 libmp3lame wmav2 cook ...&lt;br /&gt;&lt;br /&gt;    其中 H.264 是最流行的 vcodec，也叫 MPEG-4 AVC、MPEG-4 part 10，对cpu等硬件要求较高，目前高&lt;br /&gt;清用 H.264、MPEG-2 的最多。&lt;br /&gt;    &lt;br /&gt;    DVD 电影扩展名为 .vob，MPEG-2 + ac3、dts，vbitrate: 7Mbps&lt;br /&gt;    720P、1080P 高清电影扩展名多为 .mkv .mp4，H.264 + ac3、dts，vbitrate: 5Mbps、10Mbps&lt;br /&gt;    Blu-ray Disc 蓝光盘电影扩展名多为 .ts .m2ts   H.264、MPEG-2 + ac3、dts，vbitrate: 36Mbps&lt;br /&gt;    手机等掌上设备: mp4，MPEG-4&lt;br /&gt;    iphone 主要支持的format: mp4 mov m4v，优势是支持 H.264，也就是能看高清电影&lt;br /&gt;&lt;br /&gt;    .mov 多用来做高清1080P的电影预告片: True.Grit.2010.12.25.1080P.预告片.mov&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    想起了一个MM征友，说要找有品味的，比如平时谈论的是苹果五代，而不是五袋苹果的人。显然我是没&lt;br /&gt;品味的那种，因为我平时只喜欢谈论五袋苹果，不喜欢谈论苹果五代。&lt;br /&gt;&lt;br /&gt;    还有两个format平时压片尽量别用，因为它们商业味太浓，处理起来特别麻烦，尽量别用:&lt;br /&gt;    .rm           RV40 + cook&lt;br /&gt;    .wmv .asf     wmv3 + wmav2&lt;br /&gt;&lt;br /&gt;    视频操作先考虑专用工具，比如 mkvtollnix, mp4box，实在不行再用 ffmpeg，以前一直用 mencoder，&lt;br /&gt;后来发现ffmpeg问题少些，以后陆续转移到ffmpeg上来。虽然mencoder毛病很多，但由于ffmpeg无法合并视&lt;br /&gt;频，所以不能完全舍弃 mencoder。man mencoder 很有挑战性，和 mplayer 一起，参数多，跨度大，这个&lt;br /&gt;熟练后，在 man 什么都不怕了。&lt;br /&gt;&lt;br /&gt;    生成的视频 linux mplayer 总能很好的播放，所以一定要到Windows下去验证，最好直接mount一个NTFS，&lt;br /&gt;把生成的视频直接放上面。转换会有很多问题，比如转换后参数没有保持默认:bitrate被降低、视频的长宽&lt;br /&gt;比例DAR被改变、生成的视频信息封装不完整导致 file 无法识别...&lt;br /&gt;$ file out.mp4&lt;br /&gt;out.mp4: data&lt;br /&gt;&lt;br /&gt;    还有就是，无论什么方法，转换后的视频质量都会低于原质量，因此普通质量的视频无需转换，只转换&lt;br /&gt;蓝光、1080P、720P 的视频。&lt;br /&gt;&lt;br /&gt;1. 处理 mkv 用 mkvtoolnix&lt;br /&gt;$ sudo yum install mkvtoolnix&lt;br /&gt;&lt;br /&gt;生成一个mkv:&lt;br /&gt;$ mkvmerge foo.avi -o out.mkv&lt;br /&gt;$ file out.mkv&lt;br /&gt;out.mkv: Matroska data&lt;br /&gt;&lt;br /&gt;截取一段mkv。一个720P高清视频 Lin.mkv，H.264 vcodec:&lt;br /&gt;$ mkvmerge Lin.mkv --split timecodes:00:36:51,01:11:00 -o out.mkv&lt;br /&gt;生成3个mkv文件:&lt;br /&gt;out-001.mkv&lt;br /&gt;out-002.mkv&lt;br /&gt;out-003.mkv&lt;br /&gt;第二个就是想要的，码率会有很小的损失，Linux 下mplayer 或 Windows 下 Kmplayer 都能正常播放。&lt;br /&gt;目前无法直接截取第二段，可以在第二个文件split完成后手动中断mkvmerge进程。&lt;br /&gt;虽然 ffmpeg 能直接截取第二段，但操作H.264特别慢，而且不好控制，还不如直接来。&lt;br /&gt;&lt;br /&gt;PBS 纪录片 Prohibition 用 Windows kmplayer 由于库版本低无法播放，但 Linux 库版本高能播放，&lt;br /&gt;在 Linux 下做个截取的过程就能在 Windows 下播放了:&lt;br /&gt;$ ffmpeg -i PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.mkv&lt;br /&gt;  Duration: 01:33:51.77, start: 0.000000, bitrate: N/A&lt;br /&gt;    Stream #0.0(eng): Video: h264, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1(eng): Audio: aac, 48000 Hz, 5.1, s16&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ mkvmerge PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.mkv&lt;br /&gt;  --split timecodes:01:33:49&lt;br /&gt;  -o PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.out.mkv&lt;br /&gt;&lt;br /&gt;生成的文件能用 Windows kmplayer 正常播放了。&lt;br /&gt;&lt;br /&gt;合并mkv:&lt;br /&gt;$ mkvmerge 1.mkv + 2.mkv -o out.mkv&lt;br /&gt;&lt;br /&gt;港片国粤双语，只保留粤语:    ffmpeg -i 看视频参数&lt;br /&gt;$ ffmpeg -i 花样年华.2000.98min.mkv&lt;br /&gt;......&lt;br /&gt;  Duration: 01:38:51.47, start: 0.000000, bitrate: N/A&lt;br /&gt;    Stream #0.0: Video: h264, yuv420p, 668x480 [PAR 5760:4739 DAR 8016:4739], PAR 203:167 DAR 203:120, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Source:R1-US-DVD9 CRITERION COLLECTION&lt;br /&gt;    Stream #0.1: Audio: aac, 48000 Hz, stereo, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Cantonese&lt;br /&gt;    Stream #0.2: Audio: aac, 48000 Hz, stereo, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Mandarin&lt;br /&gt;    Stream #0.3(chi): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : chs&lt;br /&gt;    Stream #0.4(chi): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : cht&lt;br /&gt;    Stream #0.5(eng): Subtitle: 0x0000&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : eng&lt;br /&gt;&lt;br /&gt;可见，有2条音轨，3种字幕。要第1条audio Cantonese、前两个中文字幕chs cht。&lt;br /&gt;&lt;br /&gt;也可以用 $ mplayer -v -novideo 花样年华.2000.98min.mkv    找出 -aid 音轨号，听听验证一下:&lt;br /&gt;$ mplayer -aid 0 花样年华.2000.98min.mkv&lt;br /&gt;$ mplayer -aid 1 花样年华.2000.98min.mkv&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 花样年华.2000.98min.mkv&lt;br /&gt;File '花样年华.2000.98min.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_AAC)&lt;br /&gt;Track ID 3: audio (A_AAC)&lt;br /&gt;Track ID 4: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 5: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 6: subtitles (S_TEXT/UTF8)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 2 -s 4,5 花样年华.2000.98.min.mkv -o out.mkv &lt;br /&gt;out.mkv 确实就是粤语，码率损失很少，容量减少了约30MB。&lt;br /&gt;&lt;br /&gt;    一个视频一般只关心 Video、Audio、Subtitle 3个方面，mkvmerge -i 把这3类信息统一用一串&lt;br /&gt; Track ID 表示出来了，只要从这3个方面考虑，就很容易却别这些 TID 了。&lt;br /&gt;&lt;br /&gt;    欧美大片想让字幕默认eng，可惜 --default-track 设置后 Windows Kmplayer 还是默认中文chs，&lt;br /&gt;按照 chs eng 字母顺序来，google 说有些视频播放器 ignore default flag。&lt;br /&gt;&lt;br /&gt;普通话国产电影，去掉所有字幕:&lt;br /&gt;$ mkvmerge -S 霸王别姬.1993.mkv -o 霸王别姬.1993.out.mkv&lt;br /&gt;&lt;br /&gt;从mkv提取字幕:&lt;br /&gt;&lt;br /&gt;$ mplayer -v -novideo foo.mkv    发现是英简繁三种字幕&lt;br /&gt;$ mkvmerge -i foo.mkv &lt;br /&gt;File 'foo.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_AAC)&lt;br /&gt;Track ID 3: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 4: subtitles (S_TEXT/UTF8)&lt;br /&gt;Track ID 5: subtitles (S_TEXT/UTF8)&lt;br /&gt;&lt;br /&gt;$ mkvextract tracks foo.mkv 3:3.srt 4:4.srt 5:5.srt&lt;br /&gt;&lt;br /&gt;生成的文件为utf8编码，中文没有乱码，完全正常。&lt;br /&gt;&lt;br /&gt;提取《大话西游之仙履奇缘》的两条音轨:&lt;br /&gt;$ ffmpeg -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv&lt;br /&gt;Input #0, matroska, from 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv':&lt;br /&gt;  Metadata:&lt;br /&gt;    doctype         : matroska&lt;br /&gt;  Duration: 01:39:44.06, start: 0.000000, bitrate: 640 kb/s&lt;br /&gt;    Stream #0.0(chi): Video: h264, yuv420p, 1280x720, PAR 1:1 DAR 16:9, 24 fps, 24 tbr, 1k tbn, 48 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : A.Chinese.Odyssey.Part.Two.Cinderella.1994.x264.720p.2AUDiO.DTS.AC3.BDRiP-CHD&lt;br /&gt;    Stream #0.1(chi): Audio: dca, 48000 Hz, 6 channels, s16&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Cantonese, DTS 5.1 @ 768Kbps&lt;br /&gt;    Stream #0.2(chi): Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Mandarin, AC3 5.1 @ 640Kbps&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv &lt;br /&gt;File 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_MPEG4/ISO/AVC)&lt;br /&gt;Track ID 2: audio (A_DTS)&lt;br /&gt;Track ID 3: audio (A_AC3)&lt;br /&gt;$ sudo mkvextract tracks A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv 2:Cantonese.dts 3:Mandarin.ac3&lt;br /&gt;&lt;br /&gt;如果mount上一个Windows硬盘，把生成的字幕文件放在Windows上，由于换行符的差别，生成的文件在 Windows&lt;br /&gt; 上，整个文件就是一行。而在 linux 下对 Windows 上的 3.srt 执行 $ sudo unix2dos 3.srt  会报错。 &lt;br /&gt;因此要把生成的 3.srt 4.srt 5.srt 放在 Linux 上，执行 $ unix2dos 3.srt 4.srt 5.srt 后再放到Windows&lt;br /&gt;上。 往视频里封装srt字幕:&lt;br /&gt;&lt;br /&gt;软字幕，过后还可以extract、delete。man mkvmerge 末尾有example，中文字幕要存为 utf-8 。&lt;br /&gt;&lt;br /&gt;封装单个字幕:&lt;br /&gt;$ mkvmerge 新上海滩.1996.avi --language 0:chi 新上海滩.1996.chs.srt -o 新上海滩.1996.mkv&lt;br /&gt;&lt;br /&gt;封装多个字幕:&lt;br /&gt;$ mkvmerge foo.avi --language 0:chi foo.chs.srt --language 0:eng foo.eng.srt -o out.mkv&lt;br /&gt;&lt;br /&gt;subtitleeditor 处理字幕文件:&lt;br /&gt;$ sudo yum install subtitleeditor&lt;br /&gt;&lt;br /&gt;调节固定秒数:&lt;br /&gt;打开subtitleeditor，File --&amp;gt; Open sub 后，Ctrl+a全选，Timings --&amp;gt; Add 100 Milliseconds&lt;br /&gt;反操作就是下面的 Remove 100 Milliseconds&lt;br /&gt;如果整体调节50ms就选 Timings -&gt; Move Subtitles  自己填数字&lt;br /&gt;&lt;br /&gt;2. 处理 mp4 用 MP4Box，它隶属于 gpac&lt;br /&gt;$ sudo yum install gpac&lt;br /&gt;$ man mp4box    注意命令是 MP4Box，不是 mp4box&lt;br /&gt;&lt;br /&gt;生成mp4:&lt;br /&gt;$ MP4Box -add in.avi out.mp4&lt;br /&gt;$ file out.mp4 &lt;br /&gt;out.mp4: ISO Media, MPEG v4 system, version 1&lt;br /&gt;&lt;br /&gt;截一段mp4:&lt;br /&gt;$ MP4Box -add in.mp4 out.mp4 -splitx 60:186&lt;br /&gt;&lt;br /&gt;合并mp4:&lt;br /&gt;$ MP4Box -cat 1.mp4 -cat 2.mp4 out.mp4&lt;br /&gt;&lt;br /&gt;内嵌字幕生成mp4:  一个avi、srt，将srt嵌入到avi中，无法提取&lt;br /&gt;$ MP4Box -add "中国残留孤儿归国记.avi" -add "中国残留孤儿归国记.srt" "中国残留孤儿归国记.mp4"&lt;br /&gt;&lt;br /&gt;3. 上面两个不行了再考虑用ffmpeg，ffmpeg 不行了用mencoder。&lt;br /&gt;   比如 .wmv .mpg .flv 上面两个工具都不认、codec 转换。man ffmpeg、man mencoder&lt;br /&gt;   ffmpeg、mencoder 参数顺序很重要。&lt;br /&gt;&lt;br /&gt;截一段avi出来: vcodec 不变&lt;br /&gt;$ ffmpeg -ss 01:05:08 -t 600 -i in.avi -vcodec copy -acodec copy -o out.avi&lt;br /&gt;有时ffmpeg 截取的开始时间不准，就用 mencoder:&lt;br /&gt;$ mencoder in.avi -ovc copy -oac copy -ss 01:05:08 -endpos 600 -o out.avi&lt;br /&gt;&lt;br /&gt;一个1080p的h264视频太大，降成720p:&lt;br /&gt;$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD-002.mkv&lt;br /&gt;  Duration: 00:29:15.52, start: 0.000000, bitrate: 448 kb/s&lt;br /&gt;    Stream #0.0(eng): Video: h264, yuv420p, 1920x1080, PAR 1:1 DAR 16:9, 29.97 fps, 30 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD&lt;br /&gt;    Stream #0.1(eng): Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : AC3 5.1 channels, 448kbps&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD-002.mkv&lt;br /&gt;  -vcodec mpeg4 -b 4000k -maxrate 4200k -bufsize 1000k -r 29.97 -s hd720 -aspect 16:9 -acodec copy&lt;br /&gt;  -f matroska Journey.to.the.Edge.of.the.Universe.2008.720p.mkv&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.720p.mkv&lt;br /&gt;  Duration: 00:29:15.52, start: 0.000000, bitrate: 448 kb/s&lt;br /&gt;    Stream #0.0(eng): Video: mpeg4, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 29.97 fps, 29.92 tbr, 1k tbn, 2997 tbc&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD&lt;br /&gt;    Stream #0.1(eng): Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;    Metadata:&lt;br /&gt;      title           : AC3 5.1 channels, 448kbps&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;参数保持的很好，Windows 下播放完全正常。&lt;br /&gt;&lt;br /&gt;wmv to avi: 只转换vcodec，其它参数尽量不变，ffmpeg -i 看wmv参数&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv &lt;br /&gt;......&lt;br /&gt;  Duration: 02:31:53.32, start: 2.000000, bitrate: 560 kb/s&lt;br /&gt;    Stream #0.0: Audio: wmav2, 44100 Hz, 2 channels, s16, 64 kb/s&lt;br /&gt;    Stream #0.1: Video: wmv3, yuv420p, 640x480, 30 tbr, 1k tbn, 1k tbc&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv -vcodec mpeg4 -b 560k -maxrate 660k -bufsize 1000k -r 30&lt;br /&gt;  -acodec libmp3lame -ab 64k -ac 2 -f avi 打开记忆.avi&lt;br /&gt;&lt;br /&gt;直接 -acodec copy 没有声音，ffmpeg 处理 acodec wmav2 有问题。&lt;br /&gt;mp3 bitrate 不要小于64k，否则声音失真;&lt;br /&gt;&lt;br /&gt;将片尾曲提取出来，ffmpeg 多音轨用 -map:&lt;br /&gt;$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv&lt;br /&gt;......&lt;br /&gt;  Duration: 01:44:00.25, start: 0.000000, bitrate: 1280 kb/s&lt;br /&gt;    Stream #0.0(eng): Video: h264, yuv420p, 1280x536, PAR 1:1 DAR 160:67, 23.98 fps, 24 tbr, 1k tbn, 47.95 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s &lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s &lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv&lt;br /&gt;  -map 0:1 -acodec copy japanese.ac3 -map 0:2 -acodec copy france.ac3&lt;br /&gt;&lt;br /&gt;0:1 0:2 就是 Stream #0.1  Stream #0.2&lt;br /&gt;&lt;br /&gt;目标硬盘是mount上的NTFS，结果提取一段时间报错，不让同时write，同时 mount 假死，中断操作后，&lt;br /&gt;mount 立刻恢复了。把目标ac3 同时 write 到本机目录就不影响mount了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;从视频中提取mp3:&lt;br /&gt;$ ffmpeg -ss 00:00:00 -t 286 -i 日本通商的150年.avi -vn -acodec copy "加古隆 - JAPANデビュー.mp3"&lt;br /&gt;&lt;br /&gt;$ mencoder 日本通商的150年.avi -ovc copy -oac mp3lame -lameopts cbr:br=128:aq=0:mode=2&lt;br /&gt;  -of rawaudio -o "加古隆 - JAPANデビュー.mp3" -ss 00:00:00 -endpos 286&lt;br /&gt;&lt;br /&gt;从 wmv 提取音频:&lt;br /&gt;$ ffmpeg -i 打开记忆.wmv -vn -acodec copy -f asf 打开记忆.wma&lt;br /&gt;&lt;br /&gt;多音轨视频 VTS_01_7.vob，改变其音频参数，同时不丢失音轨:&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;-ac 5.1，现设定 -ac 2&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;加 -map 时位置很重要，下面的方式虽然也行但会损失音质:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2  &lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob -newaudio&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:03:15.89, start: 0.500000, bitrate: 6900 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x1c0]: Audio: mp2, 48000 Hz, 2 channels, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;audio 0.2 变成 mp2 了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ac3 aac wma mp3 互转:  lame 不认 wma&lt;br /&gt;$ ffmpeg -i 打开记忆.wma -vn -f mp3 打开记忆.mp3&lt;br /&gt;$ ffmpeg -i 打开记忆.mp3 -vn -f asf 打开记忆.wma&lt;br /&gt;$ ffmpeg -i 阿里山.ac3 -vn -acodec libmp3lame -ab 320k -ac 2 -f mp3 阿里山.mp3&lt;br /&gt;ac3 to mp3  要指定 -ac，虽然默认是1，但不指定不行，是个bug&lt;br /&gt;&lt;br /&gt;$ ffmpeg -formats|less    发现 ffmpeg 无法生成ape，生成ape用mac&lt;br /&gt;&lt;br /&gt;wav to ape: &lt;br /&gt;$ mac foo.wav foo.ape -c4000&lt;br /&gt;&lt;br /&gt;wv to wav: &lt;br /&gt;$ sox Kill.Bill.Vol.1.wv Kill.Bill.Vol.1.wav&lt;br /&gt;&lt;br /&gt;wav ape flac 互转:&lt;br /&gt;$ ffmpeg -i "酒井法子 - 碧いうさぎ.wav" -vn -f flac "酒井法子 - 碧いうさぎ.flac"&lt;br /&gt;&lt;br /&gt;截取[mp3|wav|flac]:&lt;br /&gt;$ ffmpeg -ss 00:02:05 -t 300 -i 打开记忆.mp3 -vn -acodec copy cut.mp3&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;合并视频:&lt;br /&gt;&lt;br /&gt;先用cat，mkvmerge、mp4box，要注意的是 ffmpeg 不能合并，要用 mencoder。&lt;br /&gt;$ cat 1.avi 2.avi 3.avi &amp;gt;&amp;gt; 1987红楼梦.avi&lt;br /&gt;$ cat 龙应台-01.mp3 龙应台-02.mp3 龙应台对话.mp3 &amp;gt;&amp;gt; 龍應台.北大.從鄉愁到美麗島.73min.24s.2010.08.01.mp3&lt;br /&gt;&lt;br /&gt;cat 有些avi可以，比如一个 DVD iso 种各个vob参数都一样，就可以直接用cat，但多数format都不能用cat，&lt;br /&gt;rm、mkv、mp4 从来没cat成功过。cat 成功与否和format关系很大，没发现和codec有关，avi h264一样合并&lt;br /&gt;成功过。&lt;br /&gt;&lt;br /&gt;$ cat 史上最牛50进球.avi 十大门将愚蠢失误.avi &amp;gt;&amp;gt; temp.avi&lt;br /&gt;生成的temp.avi合并成功了，但无法前后拖动，用mencoder -forceidx 加上 idx 就好了&lt;br /&gt;$ mencoder temp.avi -ovc copy -oac copy -forceidx -o out.avi&lt;br /&gt;&lt;br /&gt;如果mount一个Windows NTFS，想把cat生成的文件放在Windows机器上，那要用root执行，sudo 不行:&lt;br /&gt;$ sudo cat 1.avi 2.avi &amp;gt;&amp;gt; /mnt/win/out.avi&lt;br /&gt;bash: out.avi: Permission denied&lt;br /&gt;&lt;br /&gt;sudo 只对cat起作用，cat 操作升级为root，然后bash 负责 &amp;gt;&amp;gt; 操作，bash 没有被sudo提升权限。&lt;br /&gt;sudo 涉及redirection时，用 bash -c 或 tee&lt;br /&gt;$ sudo bash -c 'cat VTS_01_7.vob "孙燕姿 - 遇见.vob" &gt;&gt; /mnt/win/out.avi'&lt;br /&gt;$ cat VTS_01_7.vob "孙燕姿 - 遇见.vob" | sudo tee /mnt/win/out.avi&lt;br /&gt;看到 pipe | 不禁想到了上ftp站点在线看电影:&lt;br /&gt;$ lftp web:123@*.*.*.*&lt;br /&gt;&amp;gt; cat 日俄战争.mp4 |mplayer -&lt;br /&gt;&lt;br /&gt;一个双音轨的 DVD 文件 a.iso，把里面的文件合并成一个:&lt;br /&gt;$ sudo mount ~/a.iso /mnt/temp -o loop&lt;br /&gt;$ ls -lR /mnt/temp&lt;br /&gt;/mnt/temp:&lt;br /&gt;total 4&lt;br /&gt;dr-xr-xr-x 2 4294967295 4294967295  40 2009-05-30 19:11 AUDIO_TS&lt;br /&gt;dr-xr-xr-x 2 4294967295 4294967295 456 2009-05-30 19:11 VIDEO_TS&lt;br /&gt;&lt;br /&gt;/mnt/temp/AUDIO_TS:&lt;br /&gt;total 0&lt;br /&gt;&lt;br /&gt;/mnt/temp/VIDEO_TS:&lt;br /&gt;total 2454804&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295       8192 2009-05-30 18:41 VIDEO_TS.BUP&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295       8192 2009-05-30 18:41 VIDEO_TS.IFO&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295     133120 2009-05-30 19:11 VTS_01_0.BUP&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295     133120 2009-05-30 18:41 VTS_01_0.IFO&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295   39340032 2009-05-30 19:11 VTS_01_0.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_1.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_2.VOB&lt;br /&gt;-r--r--r-- 1 4294967295 4294967295  326965248 2009-05-30 19:11 VTS_01_3.VOB&lt;br /&gt;&lt;br /&gt;$ cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB &amp;gt;&amp;gt; out.vob&lt;br /&gt;OK了，out.vob 保持多音轨。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;西游记前25集，6张 DVD .iso 文件，国粤双语，每个 .iso 里有4集，用电脑看不方便，想单独提取出来。&lt;br /&gt;发现.iso中每一集都分为两个vob，就先合并，然后抛弃粤语音轨。&lt;br /&gt;.iso 在Windows上，直接 cat 不行，要用 bash -c&lt;br /&gt;&lt;br /&gt;$ sudo bash -c "cat VTS_01_1.VOB VTS_01_2.VOB &amp;gt;&amp;gt; 18.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_02_1.VOB VTS_02_2.VOB &amp;gt;&amp;gt; 19.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_03_1.VOB VTS_03_2.VOB &amp;gt;&amp;gt; 20.mkv"&lt;br /&gt;$ sudo bash -c "cat VTS_04_1.VOB VTS_04_2.VOB &amp;gt;&amp;gt; 21.mkv"&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge 18.vob -o 18.mkv&lt;br /&gt;$ sudo mkvmerge 19.vob -o 19.mkv&lt;br /&gt;$ sudo mkvmerge 20.vob -o 20.mkv&lt;br /&gt;$ sudo mkvmerge 21.vob -o 21.mkv&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记18.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记19.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记20.mkv&lt;br /&gt;$ sudo mkvmerge -a 2 18.mkv -o 西游记21.mkv&lt;br /&gt;&lt;br /&gt;由于同时开的mkvmerge太多，频繁写入硬盘，使得4个对应mkvmerge的进程都处于了D状态:&lt;br /&gt;&lt;br /&gt;$ top&lt;br /&gt;&lt;br /&gt;  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                              &lt;br /&gt; 1087 root      20   0     0    0    0 S  7.0  0.0  25:42.83 cifsd                                                &lt;br /&gt; 1121 root      20   0 90852  22m 9284 S  1.7  2.3  85:36.64 Xorg                                                 &lt;br /&gt;22116 cngrid    20   0 65308  18m  12m S  1.3  1.8   1:06.17 gnome-terminal                                       &lt;br /&gt;25334 root      20   0 38012 9268 2260 D  0.7  0.9   0:49.12 mkvmerge                                             &lt;br /&gt;25380 root      20   0 38300  10m 3456 D  0.7  1.1   0:48.66 mkvmerge                                             &lt;br /&gt;25424 root      20   0 37768 9024 2260 D  0.7  0.9   0:48.24 mkvmerge                                             &lt;br /&gt;25429 root      20   0 37296  10m 2372 D  0.7  1.0   0:57.04 mkvmerge             &lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;man top 说是 uninterruptible sleep，但进程仍旧继续执行，视频转换进度在不断增加。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;合并mpg:&lt;br /&gt;&lt;br /&gt;$ file *.mpg&lt;br /&gt;寻找.2004.上.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;寻找.2004.下.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 寻找.2004.上.mpg&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from '寻找.2004.上.mpg':&lt;br /&gt;  Duration: 01:07:03.01, start: 0.351433, bitrate: 1410 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x288 [PAR 178:163 DAR 1958:1467], 1150 kb/s, 25 fps, 25 tbr, 90k tbn, 25 tbc&lt;br /&gt;    Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, 2 channels, s16, 224 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 寻找.2004.上.mpg&lt;br /&gt;File '寻找.2004.上.mpg': unsupported container: RIFF CDXA&lt;br /&gt;&lt;br /&gt;mkvmerge 不认&lt;br /&gt;&lt;br /&gt;$ MP4Box -cat 寻找.2004.上.mpg -cat 寻找.2004.下.mpg 寻找.2004.mp4&lt;br /&gt;&lt;br /&gt;成功合并，bitrate 保持的很好。用mencoder也成功了，bitrate 保持的都很好:&lt;br /&gt;&lt;br /&gt;$ mencoder 寻找.2004.上.mpg 寻找.2004.下.mpg -ovc copy -oac copy&lt;br /&gt;  -of mpeg -mpegopts format=mpeg1 -o out.mpg&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;to dvd:&lt;br /&gt;$ ffmpeg -i foo.avi -target dvd out.vob&lt;br /&gt;&lt;br /&gt;to psp:&lt;br /&gt;$ ffmpeg -i foo.avi -r 29.97 -b 564k -ar 24000 -ab 64k -s 368x208 -f psp out.mp4&lt;br /&gt;&lt;br /&gt;有时生成的文件播放时图像变窄或变宽，即 Display Aspect Ratio 失调，可以用 -aspect 指定。&lt;br /&gt;&lt;br /&gt;从视频截取图片，1 fps:&lt;br /&gt;$ ffmpeg -i foo.avi -r 1 -f image2 foo-%04d.jpeg&lt;br /&gt;&lt;br /&gt;将一堆图片合成avi，0.5 fps:    如果图片名不规律就用mencoder&lt;br /&gt;$ ls|grep .png$ &amp;gt;&amp;gt; list&lt;br /&gt;$ mencoder mf://@list -mf type=png -ovc lavc -lavcopts mbd=2:trell -fps 0.5 -o out.avi&lt;br /&gt;&lt;br /&gt;从视频中截取一段，生成 Animation gif:&lt;br /&gt;$ ffmpeg -ss 00:10:00 -t 10 -i source.avi -pix_fmt rgb24 -s 360x240 out.gif&lt;br /&gt;&lt;br /&gt;1.  合并两个rm: 只为管理方便，其它参数不动&lt;br /&gt;    合并成mkv，由于ffmpeg 把视频转化成 mkv 后，file 无法识别format，还是用 mkvmerge。&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i 38度線A.rmvb &lt;br /&gt;File '38度線A.rmvb': container: RealMedia&lt;br /&gt;Track ID 0: audio (cook)&lt;br /&gt;Track ID 1: video (RV40)&lt;br /&gt;&lt;br /&gt;$ mkvmerge 38度線A.rmvb -o 38度線A.mkv &lt;br /&gt;$ mkvmerge -i 38度線A.mkv&lt;br /&gt;File '38度線A.mkv': container: Matroska&lt;br /&gt;Track ID 1: audio (A_REAL/COOK)&lt;br /&gt;Track ID 2: video (V_REAL/RV40)&lt;br /&gt;&lt;br /&gt;Windows下Kmplayer播放 38度線A.mkv 只有图像没有声音，mkvmerge 对 acodec cook 没处理好。&lt;br /&gt;用 ffmpeg 把audio提取出来转化成mp3，然后用mkvmerge封装mp3:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 38度線A.rmvb -vn -acodec libmp3lame -ab 128k 38度線A.mp3&lt;br /&gt;$ mkvmerge -A 38度線A.rmvb 38度線A.mp3 -o 38度線A.mkv&lt;br /&gt;&lt;br /&gt;可以了。38度線B.rmvb -&amp;gt; 38度線B.mkv&lt;br /&gt;$ mkvmerge 38度線A.mkv + 38度線B.mkv -o 38度線.2002.160min.mkv&lt;br /&gt;$ mkvmerge -i 38度線.2002.160min.mkv &lt;br /&gt;File '38度線.2002.160min.mkv': container: Matroska&lt;br /&gt;Track ID 1: video (V_REAL/RV40)&lt;br /&gt;Track ID 2: audio (A_MPEG/L3)&lt;br /&gt;&lt;br /&gt;可见，acodec 变成mp3了，但 vcodec 仍是real，也就是说，要想看这个mkv文件，仍需要有real decodec。&lt;br /&gt;这个例子也说明一个视频的扩展名、format只是形式，codec才是关键。 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;再合并两个rm:  辛亥双十.1.rmvb   辛亥双十.2.rmvb &lt;br /&gt;&lt;br /&gt;和上面一样，先提取出mp3，再合并。但 辛亥双十.2.rmvb 质量不行，无法用 mkvmerge直接转换成mkv:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -A 辛亥双十.2.rmvb 辛亥双十.2.mp3 -o 辛亥双十.2.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'辛亥双十.2.rmvb': Using the RealMedia demultiplexer.&lt;br /&gt;'辛亥双十.2.mp3': Using the MP2/MP3 demultiplexer.&lt;br /&gt;Warning: '辛亥双十.2.mp3': Skipping 33 bytes at the beginning (no valid MP3 header found).&lt;br /&gt;'辛亥双十.2.rmvb' track 1: Using the video output module (FourCC: RV40).&lt;br /&gt;'辛亥双十.2.mp3' track 0: Using the MPEG audio output module.&lt;br /&gt;The file '辛亥双十.2.mkv' has been opened for writing.&lt;br /&gt;Warning: '辛亥双十.2.rmvb': File contains fewer frames than expected or is corrupt after frame 46566.&lt;br /&gt;Progress: 100%&lt;br /&gt;The cue entries (the index) are being written...&lt;br /&gt;Muxing took 43 seconds.&lt;br /&gt;&lt;br /&gt;没有转换完全，Warning 说有frame corrupt。用 ffmpeg 把vcodec转化为 mpeg4 试试:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 辛亥双十.2.rmvb -vcodec mpeg4 -b 600k -acodec libmp3lame -ab 96k -ac 2 &lt;br /&gt;  -s 352x240 -r 12 辛亥双十.2.avi&lt;br /&gt;&lt;br /&gt;转换过程中 drop 很多frame，导致生成的avi audio/video 不同步，要先做同步:&lt;br /&gt;Windows 用Kmplayer 可以调整: 播放 -&amp;gt; 音频/视频同步 -&amp;gt; 重新同步音频 - 0.5 秒，试几下就行了。&lt;br /&gt;&lt;br /&gt;mplayer -delay 也可以找到所需同步时间，一点一点尝试&lt;br /&gt;$ mplayer -delay 1 辛亥双十.2.avi&lt;br /&gt;$ mplayer -delay 2 辛亥双十.2.avi&lt;br /&gt;$ mplayer -delay 3 辛亥双十.2.avi&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;但经过验证，-delay 的时间只是估计值，还要经过1、2秒钟的调整才行，最后找到audio需要延迟4500ms&lt;br /&gt;&lt;br /&gt;$ sudo mkvmerge -i 辛亥双十.2.avi&lt;br /&gt;File '辛亥双十.2.avi': container: AVI&lt;br /&gt;Track ID 0: video (FMP4)&lt;br /&gt;Track ID 1: audio (MP3)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -y 1:4500 辛亥双十.2.avi -o 辛亥双十.2.mkv&lt;br /&gt;&lt;br /&gt;同样，辛亥双十.1.rmvb 也要转换为 MPEG-4/mp3/辛亥双十.1.avi，然后 mkvmerge 成 辛亥双十.1.mkv。&lt;br /&gt;&lt;br /&gt;$ mkvmerge 辛亥双十.1.mkv + 辛亥双十.2.mkv -o 辛亥双十.1981.120min.mkv&lt;br /&gt;&lt;br /&gt;合并成功了。网上有个 x264 版本，也是460MB左右，H.264 比 MPEG-4 高效，就不共享这个了。&lt;br /&gt;&lt;br /&gt;经验就是: 压片时最好别压成 .rm  .wmv，自身质量很一般，想进行合并操作太麻烦了。&lt;br /&gt;即使压成 .rm，codec 也别用 RV40 + Cook，drop frame 太多了&lt;br /&gt;即使压成 .wmv，codec 也别用  wmv + wma&lt;br /&gt;推荐用 MPEG-4 + mp3，或者 H.264 + mp3&lt;br /&gt;&lt;br /&gt;2. 合并7个flv: 参数类型都相同，文件很小，都在5MB左右&lt;br /&gt;$ file *.flv&lt;br /&gt;01.flv: Macromedia Flash Video&lt;br /&gt;02.flv: Macromedia Flash Video&lt;br /&gt;......&lt;br /&gt;07.flv: Macromedia Flash Video&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i 01.flv&lt;br /&gt;......&lt;br /&gt;  Duration: 00:05:53.55, start: 0.000000, bitrate: 113 kb/s&lt;br /&gt;    Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 49 kb/s, 18 tbr, 1k tbn, 36 tbc&lt;br /&gt;    Stream #0.1: Audio: aac, 22050 Hz, stereo, s16, 64 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;cat不行，mkvmerge、MP4Box 不认，先用ffmpeg转成mp4，然后用MP4Box合并:&lt;br /&gt;$ ffmpeg -i 01.flv -vcodec libx264 -vpre normal -b 49k -acodec aac -strict experimental&lt;br /&gt;  -ab 64k -ac 2 -ar 22050 -s 320x240 -r 18 01.mp4&lt;br /&gt;&lt;br /&gt;$ MP4Box -cat 01.mp4 -cat 02.mp4 -cat 03.mp4 -cat 04.mp4 -cat 05.mp4 -cat 06.mp4 -cat 07.mp4 out.mp4&lt;br /&gt;&lt;br /&gt;3. 合并两个多音轨的vob:&lt;br /&gt;&lt;br /&gt;$ file "孙燕姿 - 遇见.vob" VTS_01_7.vob &lt;br /&gt;孙燕姿 - 遇见.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;VTS_01_7.vob:      MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i "孙燕姿 - 遇见.vob" -i VTS_01_7.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from '孙燕姿 - 遇见.vob':&lt;br /&gt;  Duration: 00:03:40.86, start: 786.008633, bitrate: 5120 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4225 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;[mpeg2video @ 0x918c3a0]mpeg_decode_postinit() failure&lt;br /&gt;[mpeg @ 0x918b070]max_analyze_duration reached&lt;br /&gt;Input #1, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #1.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #1.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;两个视频vcodec都是MPEG-2，都是双音轨，acodec 都是ac3。似乎一致，看能否合并:&lt;br /&gt;&lt;br /&gt;$ mkvmerge  "孙燕姿 - 遇见.vob" + VTS_01_7.vob -o out.vob&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'孙燕姿 - 遇见.vob': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_7.vob': Using the MPEG PS demultiplexer.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 1: Using the AC3 output module.&lt;br /&gt;'孙燕姿 - 遇见.vob' track 2: Using the AC3 output module.&lt;br /&gt;'VTS_01_7.vob' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'VTS_01_7.vob' track 1: Using the AC3 output module.&lt;br /&gt;'VTS_01_7.vob' track 2: Using the AC3 output module.&lt;br /&gt;No append mapping was given for the file no. 1 ('VTS_01_7.vob'). A default mapping of 1:0:0:0,1:1:0:1,1:2:0:2 will be used instead. Please keep that in mind if mkvmerge aborts with an error message regarding invalid '--append-to' options.&lt;br /&gt;Error: The track number 1 from the file 'VTS_01_7.vob' cannot be appended to the track number 1 from the file '孙燕姿 - 遇见.vob'. The track parameters do not match.&lt;br /&gt;&lt;br /&gt;无法合并，Error 说两个视频的第一条音轨的参数不同，回头细看真是不同: 一个是 stereo，另一个是 5.1。&lt;br /&gt;把 VTS_01_7.vob 的audio channel 数目降成2个再合并:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -vcodec copy -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;&lt;br /&gt;VTS.vob 只有第一条音轨，另一条丢失。&lt;br /&gt;&lt;br /&gt;$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.vob&lt;br /&gt;&lt;br /&gt;合并成功了。&lt;br /&gt;$ ffmpeg -i &lt;br /&gt;  Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s&lt;br /&gt;    Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;final.vob中，前段 "孙燕姿 - 遇见.vob" 两条音轨都有，后段 VTS.vob 也被添加了一条没有声音的新音轨。&lt;br /&gt;vbitrate 取低的192k。不足之处是前段画面的长宽变化了，后段正常。看各自的 Display Aspect Ratio，&lt;br /&gt;即DAR，分别是 16:9 和 4:3 ，一个视频的 aspect ratio 只有一个，只能将就点了。&lt;br /&gt;&lt;br /&gt;若想保持 VTS_01_7.vob 的2条音轨就用map:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob&lt;br /&gt;  -map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;参数保持的很好，合并:&lt;br /&gt;$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.mkv&lt;br /&gt;$ ffmpeg -i final.mkv&lt;br /&gt;......&lt;br /&gt;Input #0, matroska, from 'final.mkv':&lt;br /&gt;  Metadata:&lt;br /&gt;    doctype         : matroska&lt;br /&gt;  Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s&lt;br /&gt;    Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;    Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;成功了，播放正常，音轨切换也正常，想保持vob format就用mencoder。&lt;br /&gt;&lt;br /&gt;再看一个audio:&lt;br /&gt;&lt;br /&gt;$ file Eagles.Hotel.California.Original.1994.Live.vob &lt;br /&gt;Eagles.Hotel.California.Original.1994.Live.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':&lt;br /&gt;  Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s&lt;br /&gt;    Stream #0.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s&lt;br /&gt;    Stream #0.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;第一条音轨无法播放，把后两条音轨提取出来，其中0.2显示dca的不认识，先用.wav代替:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob -vn -map 0:2 -acodec copy 02.wav&lt;br /&gt;  -map 0:3 -acodec copy 03.ac3&lt;br /&gt;&lt;br /&gt;$ file 02.wav 03.ac3 &lt;br /&gt;02.wav: RIFF (little-endian) data, WAVE audio, 6 channels 48000 Hz&lt;br /&gt;03.ac3: Sendmail frozen configuration  - version \304\024\320\274*$nG\273\257\221\213\020\0256\346XQ\273&lt;br /&gt;&lt;br /&gt;两个文件 Windows 千千都能正常播放，google 知道dca就是decoding dts 的，libdca是开源的，&lt;br /&gt;$ locate libdca   可以找到 .so&lt;br /&gt;&lt;br /&gt;发现 VTS_01_7.vob 和 Eagles.Hotel.California.Original.1994.Live.vob 都有一条 ac3 5.1 audio，&lt;br /&gt;现把它们合并，最终视频只有 ac3 5.1 这一条音轨:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_7.vob -i Eagles.Hotel.California.Original.1994.Live.vob&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_7.vob':&lt;br /&gt;  Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;[mpeg @ 0x96ee4e0]max_analyze_duration reached&lt;br /&gt;Input #1, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':&lt;br /&gt;  Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s&lt;br /&gt;    Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #1.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s&lt;br /&gt;    Stream #1.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s&lt;br /&gt;    Stream #1.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i VTS_01_7.vob&lt;br /&gt;File 'VTS_01_7.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -i Eagles.Hotel.California.Original.1994.Live.vob &lt;br /&gt;File 'Eagles.Hotel.California.Original.1994.Live.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (DTS)&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 2 VTS_01_7.vob -a 1 Eagles.Hotel.California.Original.1994.Live.vob -o out.mkv&lt;br /&gt;合并失败，用 mencoder:&lt;br /&gt;&lt;br /&gt;$ mplayer -v -novideo  找到对应的 audio number 分别为 128、129&lt;br /&gt;$ mencoder VTS_01_7.vob -aid 128 Eagles.Hotel.California.Original.1994.Live.vob -aid 129&lt;br /&gt;  -ovc copy -oac copy -of mpeg -mpegopts format=dvd -o out.vob&lt;br /&gt;&lt;br /&gt;合并成功，播放正常，原来两个视频的DAR就不同，所以会有一个视频长宽比例失调，可以用 -aspect 指定。&lt;br /&gt;参数也正常:&lt;br /&gt;&lt;br /&gt;$ file out.vob&lt;br /&gt;out.vob: MPEG sequence, v2, program multiplex&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i out.vob&lt;br /&gt;Input #0, mpeg, from 'out.vob':&lt;br /&gt;  Duration: 00:11:58.41, start: 0.233367, bitrate: 5201 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;At least one output file must be specified&lt;br /&gt;&lt;br /&gt;继续尝试把 ac3 5.1 和 dts 5.1 合并，没成功。对于两个不同的codec，合并不成功很正常。&lt;br /&gt;&lt;br /&gt;4.《让子弹飞》是个双音轨的 DVD 一共7个vob，两条音轨都是国语，都有 A/V 不同步的现象，而且每个vob&lt;br /&gt; A/V 不同步程度还不同，有的差1s，有的差0.5s。现在把片源 A/V 同步，都是普通话，只留一个音轨，合并&lt;br /&gt; 成一个普通视频文件。先分别把vob转化成mkv，然后合并:&lt;br /&gt;$ mkvmerge -i VTS_01_1.VOB&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;mplayer -delay 分别试试就可以知道延迟的秒数:&lt;br /&gt;$ mplayer -delay 0.5 VTS_01_1.VOB  &lt;br /&gt;$ mplayer -delay 1 VTS_01_1.VOB    &lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:800 VTS_01_1.VOB -o out1.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'VTS_01_1.VOB': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_1.VOB': Processing the following files as well: VTS_01_2.VOB, VTS_01_3.VOB, VTS_01_4.VOB, VTS_01_5.VOB, VTS_01_6.VOB, VTS_01_7.VOB&lt;br /&gt;'VTS_01_1.VOB' track 0: Using the MPEG-1/2 video output module.&lt;br /&gt;'VTS_01_1.VOB' track 1: Using the AC3 output module.&lt;br /&gt;The file 'out1.mkv' has been opened for writing.&lt;br /&gt;Progress: 1%&lt;br /&gt;&lt;br /&gt;由shell信息知道 mkvmerge 想把这7个VOB一起处理，在这是不行的，因为每个VOB A/V 延迟秒数不同，&lt;br /&gt;所以先中断进程。建个文件夹，把其它6个VOB放进去，一个一个的分别处理:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:1000 VTS_01_1.VOB -o out1.mkv&lt;br /&gt;&lt;br /&gt;out1.mkv 比 VTS_01_1.VOB 小了30MB，小于1GB，可以分别把生成的7个mkv文件放115上给别人共享了：）&lt;br /&gt;网上一个视频如果是双语的，只要不超过1030MB 就确定可以下来，只保留一条原声，转换后就小于1GB了。&lt;br /&gt;&lt;br /&gt;其它6个VOB类似处理，每个vob的同步时间的调整都要尽量精确，因为一旦错了一个，后面的都会跟着错。可&lt;br /&gt;以在处理完前3个VOB之后，合并一下看看效果，如果不行就重新调教时间，提前发现问题。依次调教的秒数:&lt;br /&gt;&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_2.VOB -o out2.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_3.VOB -o out3.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_4.VOB -o out4.mkv&lt;br /&gt;$ mkvmerge -a 1 -y 0:100 VTS_01_5.VOB -o out5.mkv&lt;br /&gt;$ mkvmerge -a 1 VTS_01_7.VOB -o out7.mkv&lt;br /&gt;&lt;br /&gt;其中 VTS_01_6.VOB 无法处理&lt;br /&gt;$ mkvmerge -a 1 -y 0:300 VTS_01_6.VOB -o out6.mkv&lt;br /&gt;mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52&lt;br /&gt;'VTS_01_6.VOB': Using the MPEG PS demultiplexer.&lt;br /&gt;'VTS_01_6.VOB' track 0: Using the MPEG-4 part 10 ES video output module.&lt;br /&gt;'VTS_01_6.VOB' track 1: Using the AC3 output module.&lt;br /&gt;The file 'out6.mkv' has been opened for writing.&lt;br /&gt;Warning: 'VTS_01_6.VOB' track 1: This AC3 track contains 1155 bytes of non-AC3 data which were skipped. The audio/video synchronization may have been lost.&lt;br /&gt;Error: 'VTS_01_6.VOB' track 0: mkvmerge encountered broken or unparsable data in this AVC/h.264 video track. Either your file is damaged (which mkvmerge cannot cope with yet) or this is a bug in mkvmerge itself. The error message was:&lt;br /&gt;end-of-file&lt;br /&gt;&lt;br /&gt;处理前5个VOB时也会有那个Warning，但是没有Error，始终能继续处理，看下 VTS_01_6.VOB 确实和别的不同:&lt;br /&gt;$ mkvmerge -i VTS_01_6.VOB &lt;br /&gt;File 'VTS_01_6.VOB': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (AVC/h.264)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;Track ID 2: audio (AC3)&lt;br /&gt;&lt;br /&gt;video那行显示是 AVC/h.264，ffmpeg -i 显示是MPEG-2，Windows Kmplayer 也显示是 MPEG-2。&lt;br /&gt;用 ffmpeg 转化成 dvd format 看能否修复这个VOB:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB&lt;br /&gt;......&lt;br /&gt;Input #0, mpeg, from 'VTS_01_6.VOB':&lt;br /&gt;  Duration: 00:20:35.93, start: 6180.812544, bitrate: 6949 kb/s&lt;br /&gt;    Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 33.01 fps, 29.97 tbr, 90k tbn, 59.94 tbc&lt;br /&gt;    Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;    Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;音轨只要第一条&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -target dvd mid.vob&lt;br /&gt;$ mkvmerge -i mid.vob  发现没修复过来，又试几个参数都不行:&lt;br /&gt;&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -f dvd mid.vob&lt;br /&gt;$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:2 ......&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;只好 mencoder 试试:&lt;br /&gt;$ mplayer -v -novideo VTS_01_6.VOB     找到 -aid audio number，要第一条音轨 -aid 128&lt;br /&gt;$ mencoder VTS_01_6.VOB -ovc copy -oac copy -aid 128 -of mpeg -mpegopts format=dvd -o mid.vob&lt;br /&gt;$ mkvmerge -i mid.vob&lt;br /&gt;File 'mid.vob': container: MPEG 2 program stream (PS)&lt;br /&gt;Track ID 0: video (MPEG-2)&lt;br /&gt;Track ID 1: audio (AC3)&lt;br /&gt;&lt;br /&gt;正确识别为 MPEG-2 了，ffmpeg -i 发现码率保持的也很好。&lt;br /&gt;&lt;br /&gt;$ mkvmerge -y 0:1150 mid.vob -o out6.mkv&lt;br /&gt;$ mkvmerge out1.mkv + out2.mkv + out3.mkv + out4.mkv + out5.mkv + out6.mkv + out7.mkv &lt;br /&gt;  -o 让子弹飞.2010.mkv&lt;br /&gt;&lt;br /&gt;终于得到 MPEG-2 + 6 Mbps 让子弹飞.2010.mkv 了! &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-4908483760498865763?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/4908483760498865763/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/03/linuxer_31.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/4908483760498865763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/4908483760498865763'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/03/linuxer_31.html' title='linuxer'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-5331599962274170949</id><published>2010-03-28T23:09:00.005+08:00</published><updated>2010-05-15T14:03:31.050+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>delete file under Linux</title><content type='html'>&lt;pre&gt;&lt;br /&gt;先要明白Linux下delete file只是对上层目录做改变: &lt;br /&gt;目录文件的data block中存储了该目录下的所有目录项:主要2个域：inode number &amp; filename, 由于有&lt;br /&gt;inode number, 所以可以指向其它inode，也就能实现搜索了，比如 /usr/local/src/linux-2.6.33/&lt;br /&gt;&lt;br /&gt;inode中包含file的多数属性，却把filename放在了目录文件中。因此如果普通用户居然能删root的文件,&lt;br /&gt;那就看文件所在的目录是否对other开放了w权限，因为delete file是改变上层目录文件的内容，而不是file本身。&lt;br /&gt;&lt;br /&gt;$ ll /usr/local|grep src&lt;br /&gt;drwxr-xr-x.  6 root root     4096 2010-03-31 20:59 src &lt;br /&gt;$ ll /usr/local/src/&lt;br /&gt;-rw-r--r--.  1 cngrid cngrid 13864479 2009-12-01 20:15 all-20071007.tar.bz2&lt;br /&gt;dr--r--r--. 23 cngrid cngrid     4096 2010-03-30 13:58 linux-2.6.33&lt;br /&gt;-rw-r--r--.  1 cngrid cngrid  1294784 2010-03-31 18:52 linux-fetion-1.3-1.fc12.i686.rpm&lt;br /&gt;&lt;br /&gt;由于src没有对普通用户开放w权限，所以即使cngrid是src/内文件的owner，也无法删除src内的文件。&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Structure of an inode on the disk&lt;br /&gt; */&lt;br /&gt;struct ext2_inode {&lt;br /&gt;        __le16  i_mode;         /* File mode */&lt;br /&gt;        __le16  i_uid;          /* Low 16 bits of Owner Uid */&lt;br /&gt;        __le32  i_size;         /* Size in bytes */&lt;br /&gt;        __le32  i_atime;        /* Access time */&lt;br /&gt;        __le32  i_ctime;        /* Creation time */&lt;br /&gt;        __le32  i_mtime;        /* Modification time */&lt;br /&gt;        __le32  i_dtime;        /* Deletion Time */&lt;br /&gt;        __le16  i_gid;          /* Low 16 bits of Group Id */&lt;br /&gt;        __le16  i_links_count;  /* Links count */&lt;br /&gt;        __le32  i_blocks;       /* Blocks count */&lt;br /&gt;        __le32  i_flags;        /* File flags */&lt;br /&gt;        union {&lt;br /&gt;                struct {&lt;br /&gt;                        __le32  l_i_reserved1;&lt;br /&gt;                } linux1;&lt;br /&gt;                struct {&lt;br /&gt;                        __le32  h_i_translator;&lt;br /&gt;                } hurd1;&lt;br /&gt;                struct {&lt;br /&gt;                        __le32  m_i_reserved1;&lt;br /&gt;                } masix1;&lt;br /&gt;        } osd1;                         /* OS dependent 1 */&lt;br /&gt;        __le32  i_block[EXT2_N_BLOCKS];/* Pointers to blocks */&lt;br /&gt;        __le32  i_generation;   /* File version (for NFS) */&lt;br /&gt;        __le32  i_file_acl;     /* File ACL */&lt;br /&gt;        __le32  i_dir_acl;      /* Directory ACL */&lt;br /&gt;        __le32  i_faddr;        /* Fragment address */&lt;br /&gt;        union {&lt;br /&gt;                struct {&lt;br /&gt;                        __u8    l_i_frag;       /* Fragment number */&lt;br /&gt;                        __u8    l_i_fsize;      /* Fragment size */&lt;br /&gt;                        __u16   i_pad1;&lt;br /&gt;                        __le16  l_i_uid_high;   /* these 2 fields    */&lt;br /&gt;                        __le16  l_i_gid_high;   /* were reserved2[0] */&lt;br /&gt;                        __u32   l_i_reserved2;&lt;br /&gt;                } linux2;&lt;br /&gt;                struct {&lt;br /&gt;                        __u8    h_i_frag;       /* Fragment number */&lt;br /&gt;                        __u8    h_i_fsize;      /* Fragment size */&lt;br /&gt;                        __le16  h_i_mode_high;&lt;br /&gt;                        __le16  h_i_uid_high;&lt;br /&gt;                        __le16  h_i_gid_high;&lt;br /&gt;                        __le32  h_i_author;&lt;br /&gt;                } hurd2;&lt;br /&gt;                struct {&lt;br /&gt;                        __u8    m_i_frag;       /* Fragment number */&lt;br /&gt;                        __u8    m_i_fsize;      /* Fragment size */&lt;br /&gt;                        __u16   m_pad1;&lt;br /&gt;                        __u32   m_i_reserved2[2];&lt;br /&gt;                } masix2;&lt;br /&gt;        } osd2;                         /* OS dependent 2 */&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;i_block[] 就是多级寻址数组，容量为15。&lt;br /&gt;前12个指针直接指向block，后3个指针分别对应1级，2级，3级寻址:&lt;br /&gt;&lt;br /&gt;#define EXT2_NDIR_BLOCKS                12&lt;br /&gt;#define EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS&lt;br /&gt;#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)&lt;br /&gt;#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)&lt;br /&gt;#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Structure of a directory entry&lt;br /&gt; */&lt;br /&gt;#define EXT2_NAME_LEN 255&lt;br /&gt;&lt;br /&gt;struct ext2_dir_entry { &lt;br /&gt;        __le32  inode;                  /* Inode number */&lt;br /&gt;        __le16  rec_len;                /* Directory entry length */&lt;br /&gt;        __le16  name_len;               /* Name length */ &lt;br /&gt;        char    name[EXT2_NAME_LEN];    /* File name */ &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;inode中包含file的多数属性，却把filename放在了目录文件中。因此如果普通用户居然能删root的文件,&lt;br /&gt;那就看文件所在的目录是否对other开放了w权限，因为delete file是改变上层目录文件的内容，而不是&lt;br /&gt;file本身。&lt;br /&gt;&lt;br /&gt;发现一些现象:&lt;br /&gt;&lt;br /&gt;openoffice打开一个.doc，这边看着，桌面那边可以直接删除，等这边关闭后，没有save提示，直接退出，&lt;br /&gt;.doc丢失。&lt;br /&gt;&lt;br /&gt;smplayer看1.4G的movie，正看着，在xterm里可以用rm -rf 删除，ls看不见了，这边丝毫没影响，照样看，&lt;br /&gt;只要别想着关了重来就一直能看到完。但du却发现硬盘空闲空间并未增加，所以不是真删除。直到关了&lt;br /&gt;smplayer用du才发现空间释放了。&lt;br /&gt;&lt;br /&gt;有时mldonkey下一个非常想看的电影，马上就要下完了所以就等着，见下完了马上浏览，发现是打着兰兰的&lt;br /&gt;旗号的欧美烂片，马上删除。但是刚删后用du发现硬盘空余空间没增加，这说明mldonkey中有thread正在对&lt;br /&gt;刚下完的文件执行一些很慢的操作，还没等执行完呢，我就把文件删了，但只要那个thread不退出，rm -rf&lt;br /&gt;操作就不会反映到硬盘上。虽然ls看不到movie了，但没真正删除，直到过一段时间之后用du才发现硬盘空闲&lt;br /&gt;空间变大了。&lt;br /&gt;&lt;br /&gt;下了个ape，用xmms先听听，好就收藏，如果开头就好，那就直接mv到ape/中，这边继续听完，没影响。不&lt;br /&gt;必等到听完后在mv，也不用先退出xmms在mv。&lt;br /&gt;&lt;br /&gt;正用ftp下一个专辑，发现中途硬盘空间不够了，那只需直接mv到大的分区中就不用管了，不必中断ftp。&lt;br /&gt;&lt;br /&gt;有人用apache server，不注意把log rm或者mv了，由于server没退出，继续对write log，所以硬盘空闲空&lt;br /&gt;间在不断变小却还不能马上知道是什么进程在操作，直到 /proc/&lt;pid&gt;/fd/ 中ll找到原因。&lt;br /&gt;&lt;br /&gt;可见Linux这种删除文件的方式有好处也有坏处。VFS中的dcache部分有这个处理:&lt;br /&gt;&lt;br /&gt;首先，为了避免多个进程对同一个dentry删除多次，每个进程lookup操作时都要先dentry-&gt;d_count++。&lt;br /&gt;这种方法很常见，kernel里到处都是这种方法。&lt;br /&gt;&lt;br /&gt;其次，delete一个dentry，dentry-&gt;d_count &gt; 1时，说明除了本进程之外还有其它进程在使用，不能删除&lt;br /&gt;硬盘上的文件，所以只是把该dentry从hash queue中删除，这样其它进程VFS lookup就找不到它了。这样&lt;br /&gt;还不够，还要防止其它进程此后从硬盘上读取数据重新组装dentry，否则会导致该dentry永远无法删除。&lt;br /&gt;&lt;br /&gt;dentry-&gt;d_count == 1时，本进程本来可以删除该dentry对应的文件，但为了保证开头说的那些功能，这里&lt;br /&gt;也不能删硬盘上的文件，kernel 为此给dentry引入了一个negative状态: 只删除dentry-&gt;d_inode，然后&lt;br /&gt;dentry-&gt;d_inode = NULL; 这样虽然硬盘上文件还在，为了加快其它进程的lookup，该dentry还允许留在&lt;br /&gt;hash queue中，但不能允许其它进程访问硬盘上的文件，比如sys_open()要返回error，negative状态的引&lt;br /&gt;入就使得其它进程无法通过d_inode访问硬盘上的文件，达到目的了。&lt;br /&gt;&lt;br /&gt;dentry除了negative状态之外，还有两种状态:&lt;br /&gt;in use: dentry-&gt;d_count &gt; 0  &amp;&amp; dentry-&gt;d_inode != NULL&lt;br /&gt;unused: dentry-&gt;d_count == 0 &amp;&amp; dentry-&gt;d_inode != NULL&lt;br /&gt;&lt;br /&gt;negative和unused状态的dentry在kernel回收内存时可能被释放掉，而inuse状态的是不能被回收的。&lt;br /&gt;&lt;br /&gt;看看VFS中这部分的实现，注释说的很清楚:&lt;br /&gt;&lt;br /&gt;186 /*&lt;br /&gt;187  * This is dput&lt;br /&gt;188  *&lt;br /&gt;189  * This is complicated by the fact that we do not want to put&lt;br /&gt;190  * dentries that are no longer on any hash chain on the unused&lt;br /&gt;191  * list: we'd much rather just get rid of them immediately.&lt;br /&gt;192  *&lt;br /&gt;193  * However, that implies that we have to traverse the dentry&lt;br /&gt;194  * tree upwards to the parents which might _also_ now be&lt;br /&gt;195  * scheduled for deletion (it may have been only waiting for&lt;br /&gt;196  * its last child to go away).&lt;br /&gt;197  *&lt;br /&gt;198  * This tail recursion is done by hand as we don't want to depend&lt;br /&gt;199  * on the compiler to always get this right (gcc generally doesn't).&lt;br /&gt;200  * Real recursion would eat up our stack space.&lt;br /&gt;201  */&lt;br /&gt;202&lt;br /&gt;203 /*&lt;br /&gt;204  * dput - release a dentry&lt;br /&gt;205  * @dentry: dentry to release&lt;br /&gt;206  *&lt;br /&gt;207  * Release a dentry. This will drop the usage count and if appropriate&lt;br /&gt;208  * call the dentry unlink method as well as removing it from the queues and&lt;br /&gt;209  * releasing its resources. If the parent dentries were scheduled for release&lt;br /&gt;210  * they too may now get deleted.&lt;br /&gt;211  *&lt;br /&gt;212  * no dcache lock, please.&lt;br /&gt;213  */&lt;br /&gt;214&lt;br /&gt;215 void dput(struct dentry *dentry)&lt;br /&gt;216 {&lt;br /&gt;217         if (!dentry)&lt;br /&gt;218                 return;&lt;br /&gt;219&lt;br /&gt;220 repeat:&lt;br /&gt;221         if (atomic_read(&amp;dentry-&gt;d_count) == 1)&lt;br /&gt;222                 might_sleep();&lt;br /&gt;223         if (!atomic_dec_and_lock(&amp;dentry-&gt;d_count, &amp;dcache_lock))&lt;br /&gt;224                 return;&lt;br /&gt;225&lt;br /&gt;226         spin_lock(&amp;dentry-&gt;d_lock);&lt;br /&gt;227         if (atomic_read(&amp;dentry-&gt;d_count)) {&lt;br /&gt;228                 spin_unlock(&amp;dentry-&gt;d_lock);&lt;br /&gt;229                 spin_unlock(&amp;dcache_lock);&lt;br /&gt;230                 return;&lt;br /&gt;231         }&lt;br /&gt;232&lt;br /&gt;233         /*&lt;br /&gt;234          * AV: -&gt;d_delete() is _NOT_ allowed to block now.&lt;br /&gt;235          */&lt;br /&gt;236         if (dentry-&gt;d_op &amp;&amp; dentry-&gt;d_op-&gt;d_delete) {&lt;br /&gt;237                 if (dentry-&gt;d_op-&gt;d_delete(dentry))&lt;br /&gt;238                         goto unhash_it;&lt;br /&gt;239         }&lt;br /&gt;240         /* Unreachable? Get rid of it */&lt;br /&gt;241         if (d_unhashed(dentry))&lt;br /&gt;242                 goto kill_it;&lt;br /&gt;243         if (list_empty(&amp;dentry-&gt;d_lru)) {&lt;br /&gt;244                 dentry-&gt;d_flags |= DCACHE_REFERENCED;&lt;br /&gt;245                 dentry_lru_add(dentry);&lt;br /&gt;246         }&lt;br /&gt;247         spin_unlock(&amp;dentry-&gt;d_lock);&lt;br /&gt;248         spin_unlock(&amp;dcache_lock);&lt;br /&gt;249         return;&lt;br /&gt;250&lt;br /&gt;251 unhash_it:&lt;br /&gt;252         __d_drop(dentry);&lt;br /&gt;253 kill_it:&lt;br /&gt;254         /* if dentry was on the d_lru list delete it from there */&lt;br /&gt;255         dentry_lru_del(dentry);&lt;br /&gt;256         dentry = d_kill(dentry);&lt;br /&gt;257         if (dentry)&lt;br /&gt;258                 goto repeat;&lt;br /&gt;259 }&lt;br /&gt;&lt;br /&gt;dput() -&gt; d_delete()&lt;br /&gt;&lt;br /&gt;1487 /*&lt;br /&gt;1488  * When a file is deleted, we have two options:&lt;br /&gt;1489  * - turn this dentry into a negative dentry&lt;br /&gt;1490  * - unhash this dentry and free it.&lt;br /&gt;1491  *&lt;br /&gt;1492  * Usually, we want to just turn this into&lt;br /&gt;1493  * a negative dentry, but if anybody else is&lt;br /&gt;1494  * currently using the dentry or the inode&lt;br /&gt;1495  * we can't do that and we fall back on removing&lt;br /&gt;1496  * it from the hash queues and waiting for&lt;br /&gt;1497  * it to be deleted later when it has no users&lt;br /&gt;1498  */&lt;br /&gt;1499&lt;br /&gt;1500 /**&lt;br /&gt;1501  * d_delete - delete a dentry&lt;br /&gt;1502  * @dentry: The dentry to delete&lt;br /&gt;1503  *&lt;br /&gt;1504  * Turn the dentry into a negative dentry if possible, otherwise&lt;br /&gt;1505  * remove it from the hash queues so it can be deleted later&lt;br /&gt;1506  */&lt;br /&gt;1507&lt;br /&gt;1508 void d_delete(struct dentry * dentry)&lt;br /&gt;1509 {&lt;br /&gt;1510         int isdir = 0;&lt;br /&gt;1511         /*&lt;br /&gt;1512          * Are we the only user?&lt;br /&gt;1513          */&lt;br /&gt;1514         spin_lock(&amp;dcache_lock);&lt;br /&gt;1515         spin_lock(&amp;dentry-&gt;d_lock);&lt;br /&gt;1516         isdir = S_ISDIR(dentry-&gt;d_inode-&gt;i_mode);&lt;br /&gt;1517         if (atomic_read(&amp;dentry-&gt;d_count) == 1) {      // into negative&lt;br /&gt;1518                 dentry_iput(dentry);&lt;br /&gt;1519                 fsnotify_nameremove(dentry, isdir);&lt;br /&gt;1520                 return;&lt;br /&gt;1521         }&lt;br /&gt;1522&lt;br /&gt;1523         if (!d_unhashed(dentry))&lt;br /&gt;1524                 __d_drop(dentry);      // unhash&lt;br /&gt;1525&lt;br /&gt;1526         spin_unlock(&amp;dentry-&gt;d_lock);&lt;br /&gt;1527         spin_unlock(&amp;dcache_lock);&lt;br /&gt;1528&lt;br /&gt;1529         fsnotify_nameremove(dentry, isdir);&lt;br /&gt;1530 }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;dput() -&gt; d_delete() -&gt; dentry_iput()&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Release the dentry's inode, using the filesystem&lt;br /&gt; * d_iput() operation if defined.&lt;br /&gt; */&lt;br /&gt;static void dentry_iput(struct dentry * dentry)&lt;br /&gt;        __releases(dentry-&gt;d_lock)&lt;br /&gt;        __releases(dcache_lock)&lt;br /&gt;{&lt;br /&gt;        struct inode *inode = dentry-&gt;d_inode;&lt;br /&gt;        if (inode) {&lt;br /&gt;                dentry-&gt;d_inode = NULL;&lt;br /&gt;                list_del_init(&amp;dentry-&gt;d_alias);&lt;br /&gt;                spin_unlock(&amp;dentry-&gt;d_lock);&lt;br /&gt;                spin_unlock(&amp;dcache_lock);&lt;br /&gt;                if (!inode-&gt;i_nlink)&lt;br /&gt;                        fsnotify_inoderemove(inode);&lt;br /&gt;                if (dentry-&gt;d_op &amp;&amp; dentry-&gt;d_op-&gt;d_iput)&lt;br /&gt;                        dentry-&gt;d_op-&gt;d_iput(dentry, inode);&lt;br /&gt;                else&lt;br /&gt;                        iput(inode);&lt;br /&gt;        } else {&lt;br /&gt;                spin_unlock(&amp;dentry-&gt;d_lock);&lt;br /&gt;                spin_unlock(&amp;dcache_lock);&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;dput() -&gt; d_delete() -&gt; __d_drop()&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * d_drop - drop a dentry&lt;br /&gt; * @dentry: dentry to drop&lt;br /&gt; *&lt;br /&gt; * d_drop() unhashes the entry from the parent dentry hashes, so that it won't&lt;br /&gt; * be found through a VFS lookup any more. Note that this is different from&lt;br /&gt; * deleting the dentry - d_delete will try to mark the dentry negative if&lt;br /&gt; * possible, giving a successful _negative_ lookup, while d_drop will&lt;br /&gt; * just make the cache lookup fail.&lt;br /&gt; *&lt;br /&gt; * d_drop() is used mainly for stuff that wants to invalidate a dentry for some&lt;br /&gt; * reason (NFS timeouts or autofs deletes).&lt;br /&gt; *&lt;br /&gt; * __d_drop requires dentry-&gt;d_lock.&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;static inline void __d_drop(struct dentry *dentry)&lt;br /&gt;{&lt;br /&gt;        if (!(dentry-&gt;d_flags &amp; DCACHE_UNHASHED)) {&lt;br /&gt;                dentry-&gt;d_flags |= DCACHE_UNHASHED;&lt;br /&gt;                hlist_del_rcu(&amp;dentry-&gt;d_hash);&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6431648168352285436-5331599962274170949?l=imagewzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://imagewzh.blogspot.com/feeds/5331599962274170949/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://imagewzh.blogspot.com/2010/03/delete-file-under-linux.html#comment-form' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5331599962274170949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6431648168352285436/posts/default/5331599962274170949'/><link rel='alternate' type='text/html' href='http://imagewzh.blogspot.com/2010/03/delete-file-under-linux.html' title='delete file under Linux'/><author><name>imagewzh</name><uri>http://www.blogger.com/profile/11700490694506095258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_gzX6kjUIKrc/Sgmv6BCBDbI/AAAAAAAAAAg/oser5Egzb9s/S220/penguin.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6431648168352285436.post-8824380839360008556</id><published>2010-03-24T19:18:00.001+08:00</published><updated>2010-03-27T00:09:52.243+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux kernel'/><title type='text'>init process and process exit</title><content type='html'>&lt;pre&gt;&lt;br /&gt;    假设kernel编译成CONFIG_PREEMPT_NONE。&lt;br /&gt;&lt;br /&gt;    一个进程B退出时执行do_exit()，释放自己占有的绝大多数资源如memory、fd等，但和kernel stack&lt;br /&gt;有关的task_struct以及struct thread_info不会立刻被释放，因为thread_info中含有exit status，&lt;br /&gt;parent有时会通过这个exit status了解child执行时遇到的问题，parent通过waitpid()来获取这个&lt;br /&gt;exit status。还有就是进程处于切换阶段但还没切换到新进程时，如果发生了中断，ISR可能会利用待退出&lt;br /&gt;进程的kernel stack，此时就暂时保留退出进程的kernel stack，进程切换之后在释放。如果能做到中断处&lt;br /&gt;理时不依赖刚刚退出进程的kernel stack，那后一条原因就没了。&lt;br /&gt;   &lt;br /&gt;几个常识:&lt;br /&gt;thread group 可以 man clone，为了简化源码，这里假设B所在的 thread group 就他一个。&lt;br /&gt;1. fork()时，tsk-&amp;gt;usage = 2;  进程退出时释放kernel stack过程的复杂就在于这个usage=2。&lt;br /&gt;2. init在启动阶段会设置SIGCHLD handler，在handler函数中调用wait_pid()，然后while(1)做其它事。&lt;br /&gt;3. waitpid()工作过程:先执行add waitqueue操作，设置状态为TASK_INTERRUPTIBLE，然后调用schedule()&lt;br /&gt;   让出cpu，将来child用wakeup使得parent有机会重新得到执行，开始处理zombie进程，执行一次&lt;br /&gt;   release_task() usage--，此时usage=1，所以不释放退出进程的kernel stack。&lt;br /&gt;&lt;br /&gt;    总体过程是无论进程变成EXIT_DEAD自己self reap还是变成EXIT_ZOMBIE让init处理。都是先执行一次&lt;br /&gt;release_task()做一次usage--，然后退出进程在do_exit()末尾执行schedule()，在schedule()中第二次执&lt;br /&gt;行release_task()，此时usage=0，释放B的kernel stack。&lt;br /&gt;&lt;br /&gt;    EXIT_DEAD 状态self reap时自己执行第一次release_task()，&lt;br /&gt;    EXIT_ZOMBIE 状态是由waitpid()执行的第一次release_task()，&lt;br /&gt;    而两种情况下，第二次release_task()都是自己在schedule()中执行的。也就是说，最后释放&lt;br /&gt;    kernel stack的工作还要靠退出进程自己执行schedule()来完成，而不是由init释放的。&lt;br /&gt;&lt;br /&gt;进程处于EXIT_ZOMBIE状态就是一个进程就剩下kernel stack了，正等着被释放。此时 ps aux |grep Z&lt;br /&gt;能够看见。但如果长时间存在，系统会变慢。google发现原因很多，有的说application, libc, kernel&lt;br /&gt;都有嫌疑，这里看了一些源码发现kernel对 EXIT_ZOMBIE 处理的很全面，应该不是kernel的原因。&lt;br /&gt;&lt;br /&gt;如果B的parent是init，B退出了，那回收过程如下:&lt;br /&gt;&lt;br /&gt;1) B退出时先给自己的孩子C1,C2...等找养父。找养父的过程是：先在本thread group中找一个B1做为C1,&lt;br /&gt;   C2,...的养父，如果thread group中只有B自己，那就让init做C1,C2...的养父。然后B给init发SIGCHLD&lt;br /&gt;   信号，信号中携带B的exit status。&lt;br /&gt;&lt;br /&gt;2) init收到SIGCHLD，进入handler，执行wait_pid()。wait_pid()执行add waitqueue，然后调用&lt;br /&gt;   schedule()让出cpu。&lt;br /&gt;&lt;br /&gt;3) B继续执行wakeup函数让init有机会得到运行，B设置自己状态为 TASK_ZOMBIE。init重新运行后开始&lt;br /&gt;   处理状态为TASK_ZOMBIE 的进程，执行一次release_task()，usage--，remove waitqueue。得到退出&lt;br /&gt;   进程的exit status。但不能释放B的kernel stack，&lt;br /&gt;&lt;br /&gt;4) B继续在do_exit()末尾执行schedule()，在里面的finish_task_switch()中再执行一次release_task()，&lt;br /&gt;   这次usage--之后终于可以释放kernel stack了。&lt;br /&gt;&lt;br /&gt;而状态为 EXIT_DEAD 的进程是self reap:&lt;br /&gt;自己先执行一次release_task()，然后在schedule()中再执行一次release_task()释放kernel stack。&lt;br /&gt;&lt;br /&gt;man waitpid&lt;br /&gt;&lt;br /&gt;POSIX.1-2001  specifies  that  if  the disposition of SIGCHLD is set to SIG_IGN or the&lt;br /&gt;SA_NOCLDWAIT flag is set for SIGCHLD, then children that terminate do not become zombies.&lt;br /&gt;Linux 2.6 conforms to this  specification.&lt;br /&gt;&lt;br /&gt;man 7 signal 发现SIGCHLD对应的Action是Ign，所以即使parent不调用waitpid()，也不会产生zombie。&lt;br /&gt;&lt;br /&gt;下面用init源码，do_exit()和sys_waitpid()验证一下:&lt;br /&gt;&lt;br /&gt;# rpm -qif /sbin/init      知道init源码在SysVinit包里，init.c 中main()&lt;br /&gt;&lt;br /&gt;2594 /*&lt;br /&gt;2595  * Main entry for init and telinit.&lt;br /&gt;2596  */&lt;br /&gt;2597 int main(int argc, char **argv)&lt;br /&gt;2598 {&lt;br /&gt;2599         char                    *p;&lt;br /&gt;2600         int                     f;&lt;br /&gt;2601         int                     isinit;&lt;br /&gt;2602 &lt;br /&gt;2603         /* Get my own name */&lt;br /&gt;2604         if ((p = strrchr(argv[0], '/')) != NULL)&lt;br /&gt;2605                 p++;&lt;br /&gt;2606         else&lt;br /&gt;2607                 p = argv[0];&lt;br /&gt;2608         umask(022);&lt;br /&gt;2609 &lt;br /&gt;2610         /* Quick check */&lt;br /&gt;2611         if (geteuid() != 0) {&lt;br /&gt;2612                 fprintf(stderr, "%s: must be superuser.\n", p);&lt;br /&gt;2613                 exit(1);&lt;br /&gt;2614         }&lt;br /&gt;2615 &lt;br /&gt;2616         /*&lt;br /&gt;2617          *      Is this telinit or init ?&lt;br /&gt;2618          */&lt;br /&gt;2619         isinit = (getpid() == 1);&lt;br /&gt;2620         for (f = 1; f &amp;lt; argc; f++) {&lt;br /&gt;2621                 if (!strcmp(argv[f], "-i") || !strcmp(argv[f], "--init"))&lt;br /&gt;2622                         isinit = 1;&lt;br /&gt;2623                         break;&lt;br /&gt;2624         }&lt;br /&gt;2625         if (!isinit) exit(telinit(p, argc, argv));&lt;br /&gt;2626 &lt;br /&gt;2627         /*&lt;br /&gt;2628          *      Check for re-exec&lt;br /&gt;2629          */&lt;br /&gt;2630         if (check_pipe(STATE_PIPE)) {&lt;br /&gt;2631 &lt;br /&gt;2632                 receive_state(STATE_PIPE);&lt;br /&gt;2633 &lt;br /&gt;2634                 myname = istrdup(argv[0]);&lt;br /&gt;2635                 argv0 = argv[0];&lt;br /&gt;2636                 maxproclen = 0;&lt;br /&gt;2637                 for (f = 0; f &amp;lt; argc; f++)&lt;br /&gt;2638                         maxproclen += strlen(argv[f]) + 1;&lt;br /&gt;2639                 reload = 1;&lt;br /&gt;2640                 setproctitle("init [%c]",runlevel);&lt;br /&gt;2641 &lt;br /&gt;2642                 init_main();&lt;br /&gt;2643         }&lt;br /&gt;2644 &lt;br /&gt;2645         /* Check command line arguments */&lt;br /&gt;2646         maxproclen = strlen(argv[0]) + 1;&lt;br /&gt;2647         for(f = 1; f &amp;lt; argc; f++) {&lt;br /&gt;2648                 if (!strcmp(argv[f], "single") || !strcmp(argv[f], "-s"))&lt;br /&gt;2649                         dfl_level = 'S';&lt;br /&gt;2650                 else if (!strcmp(argv[f], "-a") || !strcmp(argv[f], "auto"))&lt;br /&gt;2651                         putenv("AUTOBOOT=YES");&lt;br /&gt;2652                 else if (!strcmp(argv[f], "-b") || !strcmp(argv[f],"emergency"))&lt;br /&gt;2653                         emerg_shell = 1;&lt;br /&gt;2654                 else if (!strcmp(argv[f], "-z")) {&lt;br /&gt;2655                         /* Ignore -z xxx */&lt;br /&gt;2656                         if (argv[f + 1]) f++;&lt;br /&gt;2657                 } else if (strchr("0123456789sS", argv[f][0])&lt;br /&gt;2658                         &amp;&amp; strlen(argv[f]) == 1)&lt;br /&gt;2659                         dfl_level = argv[f][0];&lt;br /&gt;2660                 /* "init u" in the very beginning makes no sense */&lt;br /&gt;2661                 if (dfl_level == 's') dfl_level = 'S';&lt;br /&gt;2662                 maxproclen += strlen(argv[f]) + 1;&lt;br /&gt;2663         }&lt;br /&gt;2664 &lt;br /&gt;2665         /* Start booting. */&lt;br /&gt;2666         argv0 = argv[0];&lt;br /&gt;2667         argv[1] = NULL;&lt;br /&gt;2668         setproctitle("init boot");&lt;br /&gt;2669         init_main(dfl_level);&lt;br /&gt;2670 &lt;br /&gt;2671         /*NOTREACHED*/&lt;br /&gt;2672         return 0;&lt;br /&gt;2673 }&lt;br /&gt;&lt;br /&gt;main() -&amp;gt; init_main()&lt;br /&gt;&lt;br /&gt;2340 /*&lt;br /&gt;2341  *      The main loop&lt;br /&gt;2342  */&lt;br /&gt;2343 int init_main()&lt;br /&gt;2344 {&lt;br /&gt;2345   CHILD                 *ch;&lt;br /&gt;2346   struct sigaction      sa;&lt;br /&gt;2347   sigset_t              sgt;&lt;br /&gt;2348   pid_t                 rc;&lt;br /&gt;2349   int                   f, st;&lt;br /&gt;2350 &lt;br /&gt;2351   if (!reload) {&lt;br /&gt;2352 &lt;br /&gt;2353 #if INITDEBUG&lt;br /&gt;2354         /*&lt;br /&gt;2355          * Fork so we can debug the init process.&lt;br /&gt;2356          */&lt;br /&gt;2357         if ((f = fork()) &amp;gt; 0) {&lt;br /&gt;2358                 static const char killmsg[] = "PRNT: init killed.\r\n";&lt;br /&gt;2359                 pid_t rc;&lt;br /&gt;2360 &lt;br /&gt;2361                 while((rc = wait(&amp;st)) != f)&lt;br /&gt;2362                         if (rc &amp;lt; 0 &amp;&amp; errno == ECHILD)&lt;br /&gt;2363                                 break;&lt;br /&gt;2364                 write(1, killmsg, sizeof(killmsg) - 1);&lt;br /&gt;2365                 while(1) pause();&lt;br /&gt;2366         }&lt;br /&gt;2367 #endif&lt;br /&gt;2368 &lt;br /&gt;2369 #ifdef __linux__&lt;br /&gt;2370         /*&lt;br /&gt;2371          *      Tell the kernel to send us SIGINT when CTRL-ALT-DEL&lt;br /&gt;2372          *      is pressed, and that we want to handle keyboard signals.&lt;br /&gt;2373          */&lt;br /&gt;2374         init_reboot(BMAGIC_SOFT);&lt;br /&gt;2375         if ((f = open(VT_MASTER, O_RDWR | O_NOCTTY)) &amp;gt;= 0) {&lt;br /&gt;2376                 (void) ioctl(f, KDSIGACCEPT, SIGWINCH);&lt;br /&gt;2377                 close(f);&lt;br /&gt;2378         } else&lt;br /&gt;2379                 (void) ioctl(0, KDSIGACCEPT, SIGWINCH);&lt;br /&gt;2380 #endif&lt;br /&gt;2381 &lt;br /&gt;2382         /*&lt;br /&gt;2383          *      Ignore all signals.&lt;br /&gt;2384          */&lt;br /&gt;2385         for(f = 1; f &amp;lt;= NSIG; f++)&lt;br /&gt;2386                 SETSIG(sa, f, SIG_IGN, SA_RESTART);&lt;br /&gt;2387   }&lt;br /&gt;2388 &lt;br /&gt;2389   SETSIG(sa, SIGALRM,  signal_handler, 0);&lt;br /&gt;2390   SETSIG(sa, SIGHUP,   signal_handler, 0);&lt;br /&gt;2391   SETSIG(sa, SIGINT,   signal_handler, 0);&lt;br /&gt;2392   SETSIG(sa, SIGCHLD,  chld_handler, SA_RESTART);&lt;br /&gt;2393   SETSIG(sa, SIGPWR,   signal_handler, 0);&lt;br /&gt;2394   SETSIG(sa, SIGWINCH, signal_handler, 0);&lt;br /&gt;2395   SETSIG(sa, SIGUSR1,  signal_handler, 0);&lt;br /&gt;2396   SETSIG(sa, SIGSTOP,  stop_handler, SA_RESTART);&lt;br /&gt;2397   SETSIG(sa, SIGTSTP,  stop_handler, SA_RESTART);&lt;br /&gt;2398   SETSIG(sa, SIGCONT,  cont_handler, SA_RESTART);&lt;br /&gt;2399   SETSIG(sa, SIGSEGV,  (void (*)(int))segv_handler, SA_RESTART);&lt;br /&gt;2400 &lt;br /&gt;2401   console_init();&lt;br /&gt;2402 &lt;br /&gt;2403   if (!reload) {&lt;br /&gt;2404 &lt;br /&gt;2405         /* Close whatever files are open, and reset the console. */&lt;br /&gt;2406         close(0);&lt;br /&gt;2407         close(1);&lt;br /&gt;2408         close(2);&lt;br /&gt;2409         console_stty();&lt;br /&gt;2410         setsid();&lt;br /&gt;2411 &lt;br /&gt;2412         /*&lt;br /&gt;2413          *      Set default PATH variable.&lt;br /&gt;2414          */&lt;br /&gt;2415         putenv(PATH_DFL);&lt;br /&gt;2416 &lt;br /&gt;2417         /*&lt;br /&gt;2418          *      Initialize /var/run/utmp (only works if /var is on&lt;br /&gt;2419          *      root and mounted rw)&lt;br /&gt;2420          */&lt;br /&gt;2421         (void) close(open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));&lt;br /&gt;2422 &lt;br /&gt;2423         /*&lt;br /&gt;2424          *      Say hello to the world&lt;br /&gt;2425          */&lt;br /&gt;2426         initlog(L_CO, bootmsg, "booting");&lt;br /&gt;2427 &lt;br /&gt;2428         /*&lt;br /&gt;2429          *      See if we have to start an emergency shell.&lt;br /&gt;2430          */&lt;br /&gt;2431         if (emerg_shell) {&lt;br /&gt;2432                 SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);&lt;br /&gt;2433                 if (spawn(&amp;ch_emerg, &amp;f) &amp;gt; 0) {&lt;br /&gt;2434                         while((rc = wait(&amp;st)) != f)&lt;br /&gt;2435                                 if (rc &amp;lt; 0 &amp;&amp; errno == ECHILD)&lt;br /&gt;2436                                         break;&lt;br /&gt;2437                 }&lt;br /&gt;2438                 SETSIG(sa, SIGCHLD,  chld_handler, SA_RESTART);&lt;br /&gt;2439         }&lt;br /&gt;2440 &lt;br /&gt;2441         /*&lt;br /&gt;2442          *      Start normal boot procedure.&lt;br /&gt;2443          */&lt;br /&gt;2444         runlevel = '#';&lt;br /&gt;2445         read_inittab();&lt;br /&gt;2446 &lt;br /&gt;2447   } else {&lt;br /&gt;2448         /*&lt;br /&gt;2449          *      Restart: unblock signals and let the show go on&lt;br /&gt;2450          */&lt;br /&gt;2451         initlog(L_CO, bootmsg, "reloading");&lt;br /&gt;2452         sigfillset(&amp;sgt);&lt;br /&gt;2453         sigprocmask(SIG_UNBLOCK, &amp;sgt, NULL);&lt;br /&gt;2454   }&lt;br /&gt;2455   start_if_needed();&lt;br /&gt;2456 &lt;br /&gt;2457   while(1) {&lt;br /&gt;2458 &lt;br /&gt;2459      /* See if we need to make the boot transitions. */&lt;br /&gt;2460      boot_transitions();&lt;br /&gt;2461      INITDBG(L_VB, "init_main: waiting..");&lt;br /&gt;2462 &lt;br /&gt;2463      /* Check if there are processes to be waited on. */&lt;br /&gt;2464      for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2465         if ((ch-&amp;gt;flags &amp; RUNNING) &amp;&amp; ch-&amp;gt;action != BOOT) break;&lt;br /&gt;2466 &lt;br /&gt;2467 #if CHANGE_WAIT&lt;br /&gt;2468      /* Wait until we get hit by some signal. */&lt;br /&gt;2469      while (ch != NULL &amp;&amp; got_signals == 0) {&lt;br /&gt;2470         if (ISMEMBER(got_signals, SIGHUP)) {&lt;br /&gt;2471                 /* See if there are processes to be waited on. */&lt;br /&gt;2472                 for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2473                         if (ch-&amp;gt;flags &amp; WAITING) break;&lt;br /&gt;2474         }&lt;br /&gt;2475         if (ch != NULL) check_init_fifo();&lt;br /&gt;2476      }&lt;br /&gt;2477 #else /* CHANGE_WAIT */&lt;br /&gt;2478      if (ch != NULL &amp;&amp; got_signals == 0) check_init_fifo();&lt;br /&gt;2479 #endif /* CHANGE_WAIT */&lt;br /&gt;2480 &lt;br /&gt;2481      /* Check the 'failing' flags */&lt;br /&gt;2482      fail_check();&lt;br /&gt;2483 &lt;br /&gt;2484      /* Process any signals. */&lt;br /&gt;2485      process_signals();&lt;br /&gt;2486 &lt;br /&gt;2487      /* See what we need to start up (again) */&lt;br /&gt;2488      start_if_needed();&lt;br /&gt;2489   }&lt;br /&gt;2490   /*NOTREACHED*/&lt;br /&gt;2491 }&lt;br /&gt;&lt;br /&gt;SIGCHLD处理函数:&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; *      SIGCHLD: one of our children has died.&lt;br /&gt; */&lt;br /&gt;void chld_handler()&lt;br /&gt;{&lt;br /&gt;        CHILD           *ch;&lt;br /&gt;        int             pid, st;&lt;br /&gt;        int             saved_errno = errno;&lt;br /&gt;&lt;br /&gt;        /*&lt;br /&gt;         *      Find out which process(es) this was (were)&lt;br /&gt;         */&lt;br /&gt;        while((pid = waitpid(-1, &amp;st, WNOHANG)) != 0) {&lt;br /&gt;                if (errno == ECHILD) break;&lt;br /&gt;                for( ch = family; ch; ch = ch-&amp;gt;next )&lt;br /&gt;                        if ( ch-&amp;gt;pid == pid &amp;&amp; (ch-&amp;gt;flags &amp; RUNNING) ) {&lt;br /&gt;                                INITDBG(L_VB, "chld_handler: marked %d as zombie", ch-&amp;gt;pid);&lt;br /&gt;                                ADDSET(got_signals, SIGCHLD);&lt;br /&gt;                                ch-&amp;gt;exstat = st;&lt;br /&gt;                                ch-&amp;gt;flags |= ZOMBIE;&lt;br /&gt;                                if (ch-&amp;gt;new) {&lt;br /&gt;                                        ch-&amp;gt;new-&amp;gt;exstat = st;&lt;br /&gt;                                        ch-&amp;gt;new-&amp;gt;flags |= ZOMBIE;&lt;br /&gt;                                }&lt;br /&gt;                                break;&lt;br /&gt;                        }&lt;br /&gt;                if (ch == NULL)&lt;br /&gt;                        INITDBG(L_VB, "chld_handler: unknown child %d exited.", pid);&lt;br /&gt;        }&lt;br /&gt;        errno = saved_errno;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;ch-&amp;gt;exstat = st; 是目的。可见init进程也是用waitpid()获取child的exit status的，这里把SIGCHLD记录&lt;br /&gt;到全局变量got_signals中，got_signals变量的每个bit代表一种signal。&lt;br /&gt;&lt;br /&gt;最后的2457   while(1) {   循环就是平时见到的init的状态，在这等着事件发生。其中的process_signals()&lt;br /&gt;取消全局变量got_signals相应的bit。&lt;br /&gt;&lt;br /&gt;2234 /*&lt;br /&gt;2235  *      Init got hit by a signal. See which signal it is,&lt;br /&gt;2236  *      and act accordingly.&lt;br /&gt;2237  */&lt;br /&gt;2238 void process_signals()&lt;br /&gt;2239 {&lt;br /&gt;2240   CHILD         *ch;&lt;br /&gt;2241   int           pwrstat;&lt;br /&gt;2242   int           oldlevel;&lt;br /&gt;2243   int           fd;&lt;br /&gt;2244   char          c;&lt;br /&gt;2245 &lt;br /&gt;2246   if (ISMEMBER(got_signals, SIGPWR)) {&lt;br /&gt;2247         INITDBG(L_VB, "got SIGPWR");&lt;br /&gt;2248         /* See _what_ kind of SIGPWR this is. */&lt;br /&gt;2249         pwrstat = 0;&lt;br /&gt;2250         if ((fd = open(PWRSTAT, O_RDONLY)) &amp;gt;= 0) {&lt;br /&gt;2251                 c = 0;&lt;br /&gt;2252                 read(fd, &amp;c, 1);&lt;br /&gt;2253                 pwrstat = c;&lt;br /&gt;2254                 close(fd);&lt;br /&gt;2255                 unlink(PWRSTAT);&lt;br /&gt;2256         }&lt;br /&gt;2257         do_power_fail(pwrstat);&lt;br /&gt;2258         DELSET(got_signals, SIGPWR);&lt;br /&gt;2259   }&lt;br /&gt;2260 &lt;br /&gt;2261   if (ISMEMBER(got_signals, SIGINT)) {&lt;br /&gt;2262         INITDBG(L_VB, "got SIGINT");&lt;br /&gt;2263         /* Tell ctrlaltdel entry to start up */&lt;br /&gt;2264         for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2265                 if (ch-&amp;gt;action == CTRLALTDEL)&lt;br /&gt;2266                         ch-&amp;gt;flags &amp;= ~XECUTED;&lt;br /&gt;2267         DELSET(got_signals, SIGINT);&lt;br /&gt;2268   }&lt;br /&gt;2269 &lt;br /&gt;2270   if (ISMEMBER(got_signals, SIGWINCH)) {&lt;br /&gt;2271         INITDBG(L_VB, "got SIGWINCH");&lt;br /&gt;2272         /* Tell kbrequest entry to start up */&lt;br /&gt;2273         for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2274                 if (ch-&amp;gt;action == KBREQUEST)&lt;br /&gt;2275                         ch-&amp;gt;flags &amp;= ~XECUTED;&lt;br /&gt;2276         DELSET(got_signals, SIGWINCH);&lt;br /&gt;2277   }&lt;br /&gt;2278 &lt;br /&gt;2279   if (ISMEMBER(got_signals, SIGALRM)) {&lt;br /&gt;2280         INITDBG(L_VB, "got SIGALRM");&lt;br /&gt;2281         /* The timer went off: check it out */&lt;br /&gt;2282         DELSET(got_signals, SIGALRM);&lt;br /&gt;2283   }&lt;br /&gt;2284 &lt;br /&gt;2285   if (ISMEMBER(got_signals, SIGCHLD)) {&lt;br /&gt;2286         INITDBG(L_VB, "got SIGCHLD");&lt;br /&gt;2287         /* First set flag to 0 */&lt;br /&gt;2288         DELSET(got_signals, SIGCHLD);&lt;br /&gt;2289 &lt;br /&gt;2290         /* See which child this was */&lt;br /&gt;2291         for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2292             if (ch-&amp;gt;flags &amp; ZOMBIE) {&lt;br /&gt;2293                 INITDBG(L_VB, "Child died, PID= %d", ch-&amp;gt;pid);&lt;br /&gt;2294                 ch-&amp;gt;flags &amp;= ~(RUNNING|ZOMBIE|WAITING);&lt;br /&gt;2295                 if (ch-&amp;gt;process[0] != '+')&lt;br /&gt;2296                         write_utmp_wtmp("", ch-&amp;gt;id, ch-&amp;gt;pid, DEAD_PROCESS, NULL);&lt;br /&gt;2297             }&lt;br /&gt;2298 &lt;br /&gt;2299   }&lt;br /&gt;2300 &lt;br /&gt;2301   if (ISMEMBER(got_signals, SIGHUP)) {&lt;br /&gt;2302         INITDBG(L_VB, "got SIGHUP");&lt;br /&gt;2303 #if CHANGE_WAIT&lt;br /&gt;2304         /* Are we waiting for a child? */&lt;br /&gt;2305         for(ch = family; ch; ch = ch-&amp;gt;next)&lt;br /&gt;2306                 if (ch-&amp;gt;flags &amp; WAITING) break;&lt;br /&gt;2307         if (ch == NULL)&lt;br /&gt;2308 #endif&lt;br /&gt;2309         {&lt;br /&gt;2310                 /* We need to go into a new runlevel */&lt;br /&gt;2311                 oldlevel = runlevel;&lt;br /&gt;2312 #ifdef INITLVL&lt;br /&gt;2313                 runlevel = read_level(0);&lt;br /&gt;2314 #endif&lt;br /&gt;2315                 if (runlevel == 'U') {&lt;br /&gt;2316                         runlevel = oldlevel;&lt;br /&gt;2317                         re_exec();&lt;br /&gt;2318                 } else {&lt;br /&gt;2319                         if (oldlevel != 'S' &amp;&amp; runlevel == 'S') console_stty();&lt;br /&gt;2320                         if (runlevel == '6' || runlevel == '0' ||&lt;br /&gt;2321                             runlevel == '1') console_stty();&lt;br /&gt;2322                         read_inittab();&lt;br /&gt;2323                         fail_cancel();&lt;br /&gt;2324                         setproctitle("init [%c]", runlevel);&lt;br /&gt;2325                         DELSET(got_signals, SIGHUP);&lt;br /&gt;2326                 }&lt;br /&gt;2327         }&lt;br /&gt;2328   }&lt;br /&gt;2329   if (ISMEMBER(got_signals, SIGUSR1)) {&lt;br /&gt;2330         /*&lt;br /&gt;2331          *      SIGUSR1 means close and reopen /dev/initctl&lt;br /&gt;2332          */&lt;br /&gt;2333         INITDBG(L_VB, "got SIGUSR1");&lt;br /&gt;2334         close(pipe_fd);&lt;br /&gt;2335         pipe_fd = -1;&lt;br /&gt;2336         DELSET(got_signals, SIGUSR1);&lt;br /&gt;2337   }&lt;br /&gt;2338 }&lt;br /&gt;&lt;br /&gt;可见用户态的init的代码对zombie的处理很简单，关键是靠调用waitpid()，来看看sys_wait4():&lt;br /&gt;&lt;br /&gt;直接vi -t sys_waitpid()没有，grep -r 发现了 kernel/exit.c，进入搜索如下内容:&lt;br /&gt;#ifdef __ARCH_WANT_SYS_WAITPID&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * sys_waitpid() remains for compatibility. waitpid() should be&lt;br /&gt; * implemented by calling sys_wait4() from libc.a.&lt;br /&gt; */&lt;br /&gt;SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options)&lt;br /&gt;{&lt;br /&gt;        return sys_wait4(pid, stat_addr, options, NULL);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;但grep -r 也找不到sys_wait4的定义，上LXR在2.6.11中能找到定义，发现do_wait()是其核心函数，&lt;br /&gt;好在 vi -t do_wait 存在。到2.6.29就没sys_wait4()的定义了。&lt;br /&gt;&lt;br /&gt;1600 static long do_wait(struct wait_opts *wo)&lt;br /&gt;1601 {&lt;br /&gt;1602         struct task_struct *tsk;&lt;br /&gt;1603         int retval;&lt;br /&gt;1604 &lt;br /&gt;1605         trace_sched_process_wait(wo-&amp;gt;wo_pid);&lt;br /&gt;1606 &lt;br /&gt;1607         init_waitqueue_func_entry(&amp;wo-&amp;gt;child_wait, child_wait_callback);&lt;br /&gt;1608         wo-&amp;gt;child_wait.private = current;&lt;br /&gt;1609         add_wait_queue(&amp;current-&amp;gt;signal-&amp;gt;wait_chldexit, &amp;wo-&amp;gt;child_wait);&lt;br /&gt;1610 repeat:&lt;br /&gt;1611         /*&lt;br /&gt;1612          * If there is nothing that can match our critiera just get out.&lt;br /&gt;1613          * We will clear -&amp;gt;notask_error to zero if we see any child that&lt;br /&gt;1614          * might later match our criteria, even if we are not able to reap&lt;br /&gt;1615          * it yet.&lt;br /&gt;1616          */&lt;br /&gt;1617         wo-&amp;gt;notask_error = -ECHILD;&lt;br /&gt;1618         if ((wo-&amp;gt;wo_type &amp;lt; PIDTYPE_MAX) &amp;&amp;&lt;br /&gt;1619            (!wo-&amp;gt;wo_pid || hlist_empty(&amp;wo-&amp;gt;wo_pid-&amp;gt;tasks[wo-&amp;gt;wo_type])))&lt;br /&gt;1620                 goto notask;&lt;br /&gt;1621 &lt;br /&gt;1622         set_current_state(TASK_INTERRUPTIBLE);&lt;br /&gt;1623         read_lock(&amp;tasklist_lock);&lt;br /&gt;1624         tsk = current;&lt;br /&gt;1625         do {&lt;br /&gt;1626                 retval = do_wait_thread(wo, tsk);&lt;br /&gt;1627                 if (retval)&lt;br /&gt;1628                         goto end;&lt;br /&gt;1629 &lt;br /&gt;1630                 retval = ptrace_do_wait(wo, tsk);&lt;br /&gt;1631                 if (retval)&lt;br /&gt;1632                         goto end;&lt;br /&gt;1633 &lt;br /&gt;1634                 if (wo-&amp;gt;wo_flags &amp; __WNOTHREAD)&lt;br /&gt;1635                         break;&lt;br /&gt;1636         } while_each_thread(current, tsk);&lt;br /&gt;1637         read_unlock(&amp;tasklist_lock);&lt;br /&gt;1638 &lt;br /&gt;1639 notask:&lt;br /&gt;1640         retval = wo-&amp;gt;notask_error;&lt;br /&gt;1641         if (!retval &amp;&amp; !(wo-&amp;gt;wo_flags &amp; WNOHANG)) {&lt;br /&gt;1642                 retval = -ERESTARTSYS;&lt;br /&gt;1643                 if (!signal_pending(current)) {&lt;br /&gt;1644                         schedule();&lt;br /&gt;1645                         goto repeat;&lt;br /&gt;1646                 }&lt;br /&gt;1647         }&lt;br /&gt;1648 end:&lt;br /&gt;1649         __set_current_state(TASK_RUNNING);&lt;br /&gt;1650         remove_wait_queue(&amp;current-&amp;gt;signal-&amp;gt;wait_chldexit, &amp;wo-&amp;gt;child_wait);&lt;br /&gt;1651         return retval;&lt;br /&gt;1652 }&lt;br /&gt;&lt;br /&gt;do_wait() -&amp;gt; do_wait_thread()&lt;br /&gt;1543 /*&lt;br /&gt;1544  * Do the work of do_wait() for one thread in the group, @tsk.&lt;br /&gt;1545  *&lt;br /&gt;1546  * -ECHILD should be in -&amp;gt;notask_error before the first call.&lt;br /&gt;1547  * Returns nonzero for a final return, when we have unlocked tasklist_lock.&lt;br /&gt;1548  * Returns zero if the search for a child should continue; then&lt;br /&gt;1549  * -&amp;gt;notask_error is 0 if there were any eligible children,&lt;br /&gt;1550  * or another error from security_task_wait(), or still -ECHILD.&lt;br /&gt;1551  */&lt;br /&gt;1552 static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)&lt;br /&gt;1553 {&lt;br /&gt;1554         struct task_struct *p;&lt;br /&gt;1555 &lt;br /&gt;1556         list_for_each_entry(p, &amp;tsk-&amp;gt;children, sibling) {&lt;br /&gt;1557                 int ret = wait_consider_task(wo, 0, p);&lt;br /&gt;1558                 if (ret)&lt;br /&gt;1559                         return ret;&lt;br /&gt;1560         }&lt;br /&gt;1561 &lt;br /&gt;1562         return 0;&lt;br /&gt;1563 }&lt;br /&gt;&lt;br /&gt;曾误以为init是系统进程的祖先，应该权力很大，会定期扫描系统所有进程，发现ZOMBIE后就回收。&lt;br /&gt;由 list_for_each_entry(p, &amp;tsk-&amp;gt;children, sibling) 看出，原来是必须先有进程在退出时把它所有的&lt;br /&gt;儿子过继给init，之后init才有机会回收那些养子。而且init必须先受到SIGCHLD信号才会处理zombie。&lt;br /&gt;&lt;br /&gt;do_wait() -&amp;gt; do_wait_thread() -&amp;gt; wait_consider_task()&lt;br /&gt;1483 /*&lt;br /&gt;1484  * Consider @p for a wait by @parent.&lt;br /&gt;1485  *&lt;br /&gt;1486  * -ECHILD should be in -&amp;gt;notask_error before the first call.&lt;br /&gt;1487  * Returns nonzero for a final return, when we have unlocked tasklist_lock.&lt;br /&gt;1488  * Returns zero if the search for a child should continue;&lt;br /&gt;1489  * then -&amp;gt;notask_error is 0 if @p is an eligible child,&lt;br /&gt;1490  * or another error from security_task_wait(), or still -ECHILD.&lt;br /&gt;1491  */&lt;br /&gt;1492 static int wait_consider_task(struct wait_opts *wo, int ptrace,&lt;br /&gt;1493                                 struct task_struct *p)&lt;br /&gt;1494 {&lt;br /&gt;1495         int ret = eligible_child(wo, p);&lt;br /&gt;1496         if (!ret)&lt;br /&gt;1497                 return ret;&lt;br /&gt;1498 &lt;br /&gt;1499         ret = security_task_wait(p);&lt;br /&gt;1500         if (unlikely(ret &amp;lt; 0)) {&lt;br /&gt;1501                 /*&lt;br /&gt;1502                  * If we have not yet seen any eligible child,&lt;br /&gt;1503                  * then let this error code replace -ECHILD.&lt;br /&gt;1504                  * A permission error will give the user a clue&lt;br /&gt;1505                  * to look for security policy problems, rather&lt;br /&gt;1506                  * than for mysterious wait bugs.&lt;br /&gt;1507                  */&lt;br /&gt;1508                 if (wo-&amp;gt;notask_error)&lt;br /&gt;1509                         wo-&amp;gt;notask_error = ret;&lt;br /&gt;1510                 return 0;&lt;br /&gt;1511         }&lt;br /&gt;1512 &lt;br /&gt;1513         if (likely(!ptrace) &amp;&amp; unlikely(task_ptrace(p))) {&lt;br /&gt;1514                 /*&lt;br /&gt;1515                  * This child is hidden by ptrace.&lt;br /&gt;1516                  * We aren't allowed to see it now, but eventually we will.&lt;br /&gt;1517                  */&lt;br /&gt;1518                 wo-&amp;gt;notask_error = 0;&lt;br /&gt;1519                 return 0;&lt;br /&gt;1520         }&lt;br /&gt;1521 &lt;br /&gt;1522         if (p-&amp;gt;exit_state == EXIT_DEAD)&lt;br /&gt;1523                 return 0;&lt;br /&gt;1524 &lt;br /&gt;1525         /*&lt;br /&gt;1526          * We don't reap group leaders with subthreads.&lt;br /&gt;1527          */&lt;br /&gt;1528         if (p-&amp;gt;exit_state == EXIT_ZOMBIE &amp;&amp; !delay_group_leader(p))&lt;br /&gt;1529                 return wait_task_zombie(wo, p);&lt;br /&gt;1530 &lt;br /&gt;1531         /*&lt;br /&gt;1532          * It's stopped or running now, so it might&lt;br /&gt;1533          * later continue, exit, or stop again.&lt;br /&gt;1534          */&lt;br /&gt;1535         wo-&amp;gt;notask_error = 0;&lt;br /&gt;1536 &lt;br /&gt;1537         if (task_stopped_code(p, ptrace))&lt;br /&gt;1538                 return wait_task_stopped(wo, ptrace, p);&lt;br /&gt;1539 &lt;br /&gt;1540         return wait_task_continued(wo, p);&lt;br /&gt;1541 }&lt;br /&gt;&lt;br /&gt;do_wait() -&amp;gt; do_wait_thread() -&amp;gt; wait_consider_task() -&amp;gt; wait_task_zombie()&lt;br /&gt;1164 /*&lt;br /&gt;1165  * Handle sys_wait4 work for one task in state EXIT_ZOMBIE.  We hold&lt;br /&gt;1166  * read_lock(&amp;tasklist_lock) on entry.  If we return zero, we still hold&lt;br /&gt;1167  * the lock and this task is uninteresting.  If we return nonzero, we have&lt;br /&gt;1168  * released the lock and the system call should return.&lt;br /&gt;1169  */&lt;br /&gt;1170 static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)&lt;br /&gt;1171 {&lt;br /&gt;1172         unsigned long state;&lt;br /&gt;1173         int retval, status, traced;&lt;br /&gt;1174         pid_t pid = task_pid_vnr(p);&lt;br /&gt;1175         uid_t uid = __task_cred(p)-&amp;gt;uid;&lt;br /&gt;1176         struct siginfo __user *infop;&lt;br /&gt;1177 &lt;br /&gt;1178         if (!likely(wo-&amp;gt;wo_flags &amp; WEXITED))&lt;br /&gt;1179                 return 0;&lt;br /&gt;1180 &lt;br /&gt;1181         if (unlikely(wo-&amp;gt;wo_flags &amp; WNOWAIT)) {&lt;br /&gt;1182                 int exit_code = p-&amp;gt;exit_code;&lt;br /&gt;1183                 int why, status;&lt;br /&gt;1184 &lt;br /&gt;1185                 get_task_struct(p);&lt;br /&gt;1186                 read_unlock(&amp;tasklist_lock);&lt;br /&gt;1187                 if ((exit_code &amp; 0x7f) == 0) {&lt;br /&gt;1188                         why = CLD_EXITED;&lt;br /&gt;1189                         status = exit_code &amp;gt;&amp;gt; 8;&lt;br /&gt;1190                 } else {&lt;br /&gt;1191                         why = (exit_code &amp; 0x80) ? CLD_DUMPED : CLD_KILLED;&lt;br /&gt;1192                         status = exit_code &amp; 0x7f;&lt;br /&gt;1193                 }&lt;br /&gt;1194                 return wait_noreap_copyout(wo, p, pid, uid, why, status);&lt;br /&gt;1195         }&lt;br /&gt;1196 &lt;br /&gt;1197         /*&lt;br /&gt;1198          * Try to move the task's state to DEAD&lt;br /&gt;1199          * only one thread is allowed to do this:&lt;br /&gt;1200          */&lt;br /&gt;1201         state = xchg(&amp;p-&amp;gt;exit_state, EXIT_DEAD);&lt;br /&gt;1202         if (state != EXIT_ZOMBIE) {&lt;br /&gt;1203                 BUG_ON(state != EXIT_DEAD);&lt;br /&gt;1204                 return 0;&lt;br /&gt;1205         }&lt;br /&gt;1206 &lt;br /&gt;1207         traced = ptrace_reparented(p);&lt;br /&gt;1208         /*&lt;br /&gt;1209          * It can be ptraced but not reparented, check&lt;br /&gt;1210          * !task_detached() to filter out sub-threads.&lt;br /&gt;1211          */&lt;br /&gt;1212         if (likely(!traced) &amp;&amp; likely(!task_detached(p))) {&lt;br /&gt;1213                 struct signal_struct *psig;&lt;br /&gt;1214                 struct signal_struct *sig;&lt;br /&gt;1215                 unsigned long maxrss;&lt;br /&gt;1216                 cputime_t tgutime, tgstime;&lt;br /&gt;1217 &lt;br /&gt;1218                 /*&lt;br /&gt;1219                  * The resource counters for the group leader are in its&lt;br /&gt;1220                  * own task_struct.  Those for dead threads in the group&lt;br /&gt;1221                  * are in its signal_struct, as are those for the child&lt;br /&gt;1222                  * processes it has previously reaped.  All these&lt;br /&gt;1223                  * accumulate in the parent's signal_struct c* fields.&lt;br /&gt;1224                  *&lt;br /&gt;1225                  * We don't bother to take a lock here to protect these&lt;br /&gt;1226                  * p-&amp;gt;signal fields, because they are only touched by&lt;br /&gt;1227                  * __exit_signal, which runs with tasklist_lock&lt;br /&gt;1228                  * write-locked anyway, and so is excluded here.  We do&lt;br /&gt;1229                  * need to protect the access to parent-&amp;gt;signal fields,&lt;br /&gt;1230                  * as other threads in the parent group can be right&lt;br /&gt;1231                  * here reaping other children at the same time.&lt;br /&gt;1232                  *&lt;br /&gt;1233                  * We use thread_group_times() to get times for the thread&lt;br /&gt;1234                  * group, which consolidates times for all threads in the&lt;br /&gt;1235                  * group including the group leader.&lt;br /&gt;1236                  */&lt;br /&gt;1237                 thread_group_times(p, &amp;tgutime, &amp;tgstime);&lt;br /&gt;1238                 spin_lock_irq(&amp;p-&amp;gt;real_parent-&amp;gt;sighand-&amp;gt;siglock);&lt;br /&gt;1239                 psig = p-&amp;gt;real_parent-&amp;gt;signal;&lt;br /&gt;1240                 sig = p-&amp;gt;signal;&lt;br /&gt;1241                 psig-&amp;gt;cutime =&lt;br /&gt;1242                         cputime_add(psig-&amp;gt;cutime,&lt;br /&gt;1243                         cputime_add(tgutime,&lt;br /&gt;1244                                     sig-&amp;gt;cutime));&lt;br /&gt;1245                 psig-&amp;gt;cstime =&lt;br /&gt;1246                         cputime_add(psig-&amp;gt;cstime,&lt;br /&gt;1247                         cputime_add(tgstime,&lt;br /&gt;1248                                     sig-&amp;gt;cstime));&lt;br /&gt;1249                 psig-&amp;gt;cgtime =&lt;br /&gt;1250                         cputime_add(psig-&amp;gt;cgtime,&lt;br /&gt;1251                         cputime_add(p-&amp;gt;gtime,&lt;br /&gt;1252                         cputime_add(sig-&amp;gt;gtime,&lt;br /&gt;1253                                     sig-&amp;gt;cgtime)));&lt;br /&gt;1254                 psig-&amp;gt;cmin_flt +=&lt;br /&gt;1255                         p-&amp;gt;min_flt + sig-&amp;gt;min_flt + sig-&amp;gt;cmin_flt;&lt;br /&gt;1256                 psig-&amp;gt;cmaj_flt +=&lt;br /&gt;1257                         p-&amp;gt;maj_flt + sig-&amp;gt;maj_flt + sig-&amp;gt;cmaj_flt;&lt;br /&gt;1258                 psig-&amp;gt;cnvcsw +=&lt;br /&gt;1259                         p-&amp;gt;nvcsw + sig-&amp;gt;nvcsw + sig-&amp;gt;cnvcsw;&lt;br /&gt;1260                 psig-&amp;gt;cnivcsw +=&lt;br /&gt;1261                         p-&amp;gt;nivcsw + sig-&amp;gt;nivcsw + sig-&amp;gt;cnivcsw;&lt;br /&gt;1262                 psig-&amp;gt;cinblock +=&lt;br /&gt;1263                         task_io_get_inblock(p) +&lt;br /&gt;1264                         sig-&amp;gt;inblock + sig-&amp;gt;cinblock;&lt;br /&gt;1265                 psig-&amp;gt;coublock +=&lt;br /&gt;1266                         task_io_get_oublock(p) +&lt;br /&gt;1267                         sig-&amp;gt;oublock + sig-&amp;gt;coublock;&lt;br /&gt;1268                 maxrss = max(sig-&amp;gt;maxrss, sig-&amp;gt;cmaxrss);&lt;br /&gt;1269                 if (psig-&amp;gt;cmaxrss &amp;lt; maxrss)&lt;br /&gt;1270                         psig-&amp;gt;cmaxrss = maxrss;&lt;br /&gt;1271                 task_io_accounting_add(&amp;psig-&amp;gt;ioac, &amp;p-&amp;gt;ioac);&lt;br /&gt;1272                 task_io_accounting_add(&amp;psig-&amp;gt;ioac, &amp;sig-&amp;gt;ioac);&lt;br /&gt;1273                 spin_unlock_irq(&amp;p-&amp;gt;real_parent-&amp;gt;sighand-&amp;gt;siglock);&lt;br /&gt;1274         }&lt;br /&gt;1275 &lt;br /&gt;1276         /*&lt;br /&gt;1277          * Now we are sure this task is interesting, and no other&lt;br /&gt;1278          * thread can reap it because we set its state to EXIT_DEAD.&lt;br /&gt;1279          */&lt;br /&gt;1280         read_unlock(&amp;tasklist_lock);&lt;br /&gt;1281 &lt;br /&gt;1282         retval = wo-&amp;gt;wo_rusage&lt;br /&gt;1283                 ? getrusage(p, RUSAGE_BOTH, wo-&amp;gt;wo_rusage) : 0;&lt;br /&gt;1284         status = (p-&amp;gt;signal-&amp;gt;flags &amp; SIGNAL_GROUP_EXIT)&lt;br /&gt;1285                 ? p-&amp;gt;signal-&amp;gt;group_exit_code : p-&amp;gt;exit_code;&lt;br /&gt;1286         if (!retval &amp;&amp; wo-&amp;gt;wo_stat)&lt;br /&gt;1287                 retval = put_user(status, wo-&amp;gt;wo_stat);&lt;br /&gt;1288 &lt;br /&gt;1289         infop = wo-&amp;gt;wo_info;&lt;br /&gt;1290         if (!retval &amp;&amp; infop)&lt;br /&gt;1291                 retval = put_user(SIGCHLD, &amp;infop-&amp;gt;si_signo);&lt;br /&gt;1292         if (!retval &amp;&amp; infop)&lt;br /&gt;1293                 retval = put_user(0, &amp;infop-&amp;gt;si_errno);&lt;br /&gt;1294         if (!retval &amp;&amp; infop) {&lt;br /&gt;1295                 int why;&lt;br /&gt;1296 &lt;br /&gt;1297                 if ((status &amp; 0x7f) == 0) {&lt;br /&gt;1298                         why = CLD_EXITED;&lt;br /&gt;1299                         status &amp;gt;&amp;gt;= 8;&lt;br /&gt;1300                 } else {&lt;br /&gt;1301                         why = (status &amp; 0x80) ? CLD_DUMPED : CLD_KILLED;&lt;br /&gt;1302                         status &amp;= 0x7f;&lt;br /&gt;1303                 }&lt;br /&gt;1304                 retval = put_user((short)why, &amp;infop-&amp;gt;si_code);&lt;br /&gt;1305                 if (!retval)&lt;br /&gt;1306                         retval = put_user(status, &amp;infop-&amp;gt;si_status);&lt;br /&gt;1307         }&lt;br /&gt;1308         if (!retval &amp;&amp; infop)&lt;br /&gt;1309                 retval = put_user(pid, &amp;infop-&amp;gt;si_pid);&lt;br /&gt;1310         if (!retval &amp;&amp; infop)&lt;br /&gt;1311                 retval = put_user(uid, &amp;infop-&amp;gt;si_uid);&lt;br /&gt;1312         if (!retval)&lt;br /&gt;1313                 retval = pid;&lt;br /&gt;1314 &lt;br /&gt;1315         if (traced) {&lt;br /&gt;1316                 write_lock_irq(&amp;tasklist_lock);&lt;br /&gt;1317                 /* We dropped tasklist, ptracer could die and untrace */&lt;br /&gt;1318                 ptrace_unlink(p);&lt;br /&gt;1319                 /*&lt;br /&gt;1320                  * If this is not a detached task, notify the parent.&lt;br /&gt;1321                  * If it's still not detached after that, don't release&lt;br /&gt;1322                  * it now.&lt;br /&gt;1323                  */&lt;br /&gt;1324                 if (!task_detached(p)) {&lt;br /&gt;1325                         do_notify_parent(p, p-&amp;gt;exit_signal);&lt;br /&gt;1326                         if (!task_detached(p)) {&lt;br /&gt;1327                                 p-&amp;gt;exit_state = EXIT_ZOMBIE;&lt;br /&gt;1328                                 p = NULL;&lt;br /&gt;1329                         }&lt;br /&gt;1330                 }&lt;br /&gt;1331                 write_unlock_irq(&amp;tasklist_lock);&lt;br /&gt;1332         }&lt;br /&gt;1333         if (p != NULL)&lt;br /&gt;1334                 release_task(p);           // first usage--&lt;br /&gt;1335 &lt;br /&gt;1336         return retval;&lt;br /&gt;1337 }&lt;br /&gt;&lt;br /&gt;进程的exit:&lt;br /&gt; 892 NORET_TYPE void do_exit(long code)&lt;br /&gt; 893 {&lt;br /&gt; 894         struct task_struct *tsk = current;&lt;br /&gt; 895         int group_dead;&lt;br /&gt; 896 &lt;br /&gt; 897         profile_task_exit(tsk);&lt;br /&gt; 898 &lt;br /&gt; 899         WARN_ON(atomic_read(&amp;tsk-&amp;gt;fs_excl));&lt;br /&gt; 900 &lt;br /&gt; 901         if (unlikely(in_interrupt()))&lt;br /&gt; 902                 panic("Aiee, killing interrupt handler!");&lt;br /&gt; 903         if (unlikely(!tsk-&amp;gt;pid))&lt;br /&gt; 904                 panic("Attempted to kill the idle task!");&lt;br /&gt; 905 &lt;br /&gt; 906         tracehook_report_exit(&amp;code);&lt;br /&gt; 907 &lt;br /&gt; 908         validate_creds_for_do_exit(tsk);&lt;br /&gt; 909 &lt;br /&gt; 910         /*&lt;br /&gt; 911          * We're taking recursive faults here in do_exit. Safest is to just&lt;br /&gt; 912          * leave this task alone and wait for reboot.&lt;br /&gt; 913          */&lt;br /&gt; 914         if (unlikely(tsk-&amp;gt;flags &amp; PF_EXITING)) {&lt;br /&gt; 915                 printk(KERN_ALERT&lt;br /&gt; 916                         "Fixing recursive fault but reboot is needed!\n");&lt;br /&gt; 917                 /*&lt;br /&gt; 918                  * We can do this unlocked here. The futex code uses&lt;br /&gt; 919                  * this flag just to verify whether the pi state&lt;br /&gt; 920                  * cleanup has been done or not. In the worst case it&lt;br /&gt; 921                  * loops once more. We pretend that the cleanup was&lt;br /&gt; 922                  * done as there is no way to return. Either the&lt;br /&gt; 923                  * OWNER_DIED bit is set by now or we push the blocked&lt;br /&gt; 924                  * task into the wait for ever nirwana as well.&lt;br /&gt; 925                  */&lt;br /&gt; 926                 tsk-&amp;gt;flags |= PF_EXITPIDONE;&lt;br /&gt; 927                 set_current_state(TASK_UNINTERRUPTIBLE);&lt;br /&gt; 928                 schedule();&lt;br /&gt; 929         }&lt;br /&gt; 930 &lt;br /&gt; 931         exit_irq_thread();&lt;br /&gt; 932 &lt;br /&gt; 933         exit_signals(tsk);  /* sets PF_EXITING */&lt;br /&gt; 934         /*&lt;br /&gt; 935          * tsk-&amp;gt;flags are checked in the futex code to protect against&lt;br /&gt; 936          * an exiting task cleaning up the robust pi futexes.&lt;br /&gt; 937          */&lt;br /&gt; 938         smp_mb();&lt;br /&gt; 939         raw_spin_unlock_wait(&amp;tsk-&amp;gt;pi_lock);&lt;br /&gt; 940 &lt;br /&gt; 941         if (unlikely(in_atomic()))&lt;br /&gt; 942                 printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",&lt;br /&gt; 943                                 current-&amp;gt;comm, task_pid_nr(current),&lt;br /&gt; 944                                 preempt_count());&lt;br /&gt; 945 &lt;br /&gt; 946         acct_update_integrals(tsk);&lt;br /&gt; 947 &lt;br /&gt; 948         group_dead = atomic_dec_and_test(&amp;tsk-&amp;gt;signal-&amp;gt;live);&lt;br /&gt; 949         if (group_dead) {&lt;br /&gt; 950                 hrtimer_cancel(&amp;tsk-&amp;gt;signal-&amp;gt;real_timer);&lt;br /&gt; 951                 exit_itimers(tsk-&amp;gt;signal);&lt;br /&gt; 952                 if (tsk-&amp;gt;mm)&lt;br /&gt; 953                         setmax_mm_hiwater_rss(&amp;tsk-&amp;gt;signal-&amp;gt;maxrss, tsk-&amp;gt;mm);&lt;br /&gt; 954         }&lt;br /&gt; 955         acct_collect(code, group_dead);&lt;br /&gt; 956         if (group_dead)&lt;br /&gt; 957                 tty_audit_exit();&lt;br /&gt; 958         if (unlikely(tsk-&amp;gt;audit_context))&lt;br /&gt; 959                 audit_free(tsk);&lt;br /&gt; 960 &lt;br /&gt; 961         tsk-&amp;gt;exit_code = code;&lt;br /&gt; 962         taskstats_exit(tsk, group_dead);&lt;br /&gt; 963 &lt;br /&gt; 964         exit_mm(tsk);&lt;br /&gt; 965 &lt;br /&gt; 966         if (group_dead)&lt;br /&gt; 967                 acct_process();&lt;br /&gt; 968         trace_sched_process_exit(tsk);&lt;br /&gt; 969 &lt;br /&gt; 970         exit_sem(tsk);&lt;br /&gt; 971         exit_files(tsk);&lt;br /&gt; 972         exit_fs(tsk);&lt;br /&gt; 973         check_stack_usage();&lt;br /&gt; 974         exit_thread();&lt;br /&gt; 975         cgroup_exit(tsk, 1);&lt;br /&gt; 976 &lt;br /&gt; 977         if (group_dead)&lt;br /&gt; 978                 disassociate_ctty(1);&lt;br /&gt; 979 &lt;br /&gt; 980         module_put(task_thread_info(tsk)-&amp;gt;exec_domain-&amp;gt;module);&lt;br /&gt; 981 &lt;br /&gt; 982         proc_exit_connector(tsk);&lt;br /&gt; 983 &lt;br /&gt; 984         /*&lt;br /&gt; 985          * FIXME: do that only when needed, using sched_exit tracepoint&lt;br /&gt; 986          */&lt;br /&gt; 987         flush_ptrace_hw_breakpoint(tsk);&lt;br /&gt; 988         /*&lt;br /&gt; 989          * Flush inherited counters to the parent - before the parent&lt;br /&gt; 990          * gets woken up by child-exit notifications.&lt;br /&gt; 991          */&lt;br /&gt; 992         perf_event_exit_task(tsk);&lt;br /&gt; 993 &lt;br /&gt; 994         exit_notify(tsk, group_dead);&lt;br /&gt; 995 #ifdef CONFIG_NUMA&lt;br /&gt; 996         mpol_put(tsk-&amp;gt;mempolicy);&lt;br /&gt; 997         tsk-&amp;gt;mempolicy = NULL;&lt;br /&gt; 998 #endif&lt;br /&gt; 999 #ifdef CONFIG_FUTEX&lt;br /&gt;1000         if (unlikely(current-&amp;gt;pi_state_cache))&lt;br /&gt;1001                 kfree(current-&amp;gt;pi_state_cache);&lt;br /&gt;1002 #endif&lt;br /&gt;1003         /*&lt;br /&gt;1004          * Make sure we are holding no locks:&lt;br /&gt;1005          */&lt;br /&gt;1006         debug_check_no_locks_held(tsk);&lt;br /&gt;1007         /*&lt;br /&gt;1008          * We can do this unlocked here. The futex code uses this flag&lt;br /&gt;1009          * just to verify whether the pi state cleanup has been done&lt;br /&gt;1010          * or not. In the worst case it loops once more.&lt;br /&gt;1011          */&lt;br /&gt;1012         tsk-&amp;gt;flags |= PF_EXITPIDONE;&lt;br /&gt;1013 &lt;br /&gt;1014         if (tsk-&amp;gt;io_context)&lt;br /&gt;1015                 exit_io_context(tsk);&lt;br /&gt;1016 &lt;br /&gt;1017         if (tsk-&amp;gt;splice_pipe)&lt;br /&gt;1018                 __free_pipe_info(tsk-&amp;gt;splice_pipe);&lt;br /&gt;1019 &lt;br /&gt;1020         validate_creds_for_do_exit(tsk);&lt;br /&gt;1021 &lt;br /&gt;1022         preempt_disable();&lt;br /&gt;1023         exit_rcu();&lt;br /&gt;1024         /* causes final put_task_struct in finish_task_switch(). */&lt;br /&gt;1025         tsk-&amp;gt;state = TASK_DEAD;&lt;br /&gt;1026         schedule();&lt;br /&gt;1027         BUG();&lt;br /&gt;1028         /* Avoid "noreturn function does return".  */&lt;br /&gt;1029         for (;;)&lt;br /&gt;1030                 cpu_relax();    /* For when BUG is null */&lt;br /&gt;1031 }&lt;br /&gt;&lt;br /&gt;注意上面函数末尾几行的注释已经说了&lt;br /&gt;1024         /* causes final put_task_struct in finish_task_switch(). */&lt;br /&gt;1025         tsk-&amp;gt;state = TASK_DEAD;&lt;br /&gt;1026         schedule();&lt;br /&gt;&lt;br /&gt;与之呼应的注释是 do_fork() -&amp;gt; copy_process() -&amp;gt; dup_task_struct()&lt;br /&gt;&lt;br /&gt; /* One for us, one for whoever does the "release_task()" (usually parent) */&lt;br /&gt; atomic_set(&amp;tsk-&amp;gt;usage,2);&lt;br /&gt;&lt;br /&gt;再看看注释说的finish_task_switch(): schedule() -&amp;gt; context_switch() -&amp;gt; finish_task_switch()&lt;br /&gt;&lt;br /&gt;2761 /**&lt;br /&gt;2762  * finish_task_switch - clean up after a task-switch&lt;br /&gt;2763  * @rq: runqueue associated with task-switch&lt;br /&gt;2764  * @prev: the thread we just switched away from.&lt;br /&gt;2765  *&lt;br /&gt;2766  * finish_task_switch must be called after the context switch, paired&lt;br /&gt;2767  * with a prepare_task_switch call before the context switch.&lt;br /&gt;2768  * finish_task_switch will reconcile locking set up by prepare_task_switch,&lt;br /&gt;2769  * and do any other architecture-specific cleanup actions.&lt;br /&gt;2770  *&lt;br /&gt;2771  * Note that we may have delayed dropping an mm in context_switch(). If&lt;br /&gt;2772  * so, we finish that here outside of the runqueue lock. (Doing it&lt;br /&gt;2773  * with the lock held can cause deadlocks; see schedule() for&lt;br /&gt;2774  * details.)&lt;br /&gt;2775  */&lt;br /&gt;2776 static void finish_task_switch(struct rq *rq, struct task_struct *prev)&lt;br /&gt;2777         __releases(rq-&amp;gt;lock)&lt;br /&gt;2778 {&lt;br /&gt;2779         struct mm_struct *mm = rq-&amp;gt;prev_mm;&lt;br /&gt;2780         long prev_state;&lt;br /&gt;2781 &lt;br /&gt;2782         rq-&amp;gt;prev_mm = NULL;&lt;br /&gt;2783 &lt;br /&gt;2784         /*&lt;br /&gt;2785          * A task struct has one reference for the use as "current".&lt;br /&gt;2786          * If a task dies, then it sets TASK_DEAD in tsk-&amp;gt;state and calls&lt;br /&gt;2787          * schedule one last time. The schedule call will never return, and&lt;br /&gt;2788          * the scheduled task must drop that reference.&lt;br /&gt;2789          * The test for TASK_DEAD must occur while the runqueue locks are&lt;br /&gt;2790          * still held, otherwise prev could be scheduled on another cpu, die&lt;br /&gt;2791          * there before we look at prev-&amp;gt;state, and then the reference would&lt;br /&gt;2792          * be dropped twice.&lt;br /&gt;2793          *              Manfred Spraul &amp;lt;manfred@colorfullife.com&amp;gt;&lt;br /&gt;2794          */&lt;br /&gt;2795         prev_state = prev-&amp;gt;state;&lt;br /&gt;2796         finish_arch_switch(prev);&lt;br /&gt;2797         perf_event_task_sched_in(current, cpu_of(rq));&lt;br /&gt;2798         finish_lock_switch(rq, prev);&lt;br /&gt;2799 &lt;br /&gt;2800         fire_sched_in_preempt_notifiers(current);&lt;br /&gt;2801         if (mm)&lt;br /&gt;2802                 mmdrop(mm);&lt;br /&gt;2803         if (unlikely(prev_state == TASK_DEAD)) {&lt;br /&gt;2804                 /*&lt;br /&gt;2805                  * Remove function-return probe instances associated with this&lt;br /&gt;2806                  * task and put them back on the free list.&lt;br /&gt;2807                  */&lt;br /&gt;2808                 kprobe_flush_task(prev);&lt;br /&gt;2809                 put_task_struct(prev);     //最终释放了退出进程的kernel stack。&lt;br /&gt;2810         }&lt;br /&gt;2811 }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;do_exit() -&amp;gt; exit_notify()&lt;br /&gt;&lt;br /&gt;803 /*&lt;br /&gt;804  * Send signals to all our closest relatives so that they know&lt;br /&gt;805  * to properly mourn us..&lt;br /&gt;806  */&lt;br /&gt;807 static void exit_notify(struct task_struct *tsk, int group_dead)&lt;br /&gt;808 {&lt;br /&gt;809         int signal;&lt;br /&gt;810         void *cookie;&lt;br /&gt;811 &lt;br /&gt;812         /*&lt;br /&gt;813          * This does two things:&lt;br /&gt;814          *&lt;br /&gt;815          * A.  Make init inherit all the child processes&lt;br /&gt;816          * B.  Check to see if any process groups have become orphaned&lt;br /&gt;817          *      as a result of our exiting, and if they have any stopped&lt;br /&gt;818          *      jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)&lt;br /&gt;819          */&lt;br /&gt;820         forget_original_parent(tsk);&lt;br /&gt;821         exit_task_namespaces(tsk);&lt;br /&gt;822 &lt;br /&gt;823         write_lock_irq(&amp;tasklist_lock);&lt;br /&gt;824         if (group_dead)&lt;br /&gt;825                 kill_orphaned_pgrp(tsk-&amp;gt;group_leader, NULL);&lt;br /&gt;826 &lt;br /&gt;827         /* Let father know we died&lt;br /&gt;828          *&lt;br /&gt;829          * Thread signals are configurable, but you aren't going to use&lt;br /&gt;830          * that to send signals to arbitary processes.&lt;br /&gt;831          * That stops right now.&lt;br /&gt;832          *&lt;br /&gt;833          * If the parent exec id doesn't match the exec id we saved&lt;br /&gt;834          * when we started then we know the parent has changed security&lt;br /&gt;835          * domain.&lt;br /&gt;836          *&lt;br /&gt;837          * If our self_exec id doesn't match our parent_exec_id then&lt;br /&gt;838          * we have changed execution domain as these two values started&lt;br /&gt;839          * the same after a fork.&lt;br /&gt;840          */&lt;br /&gt;841         if (tsk-&amp;gt;exit_signal != SIGCHLD &amp;&amp; !task_detached(tsk) &amp;&amp;&lt;br /&gt;842             (tsk-&amp;gt;parent_exec_id != tsk-&amp;gt;real_parent-&amp;gt;self_exec_id ||&lt;br /&gt;843              tsk-&amp;gt;self_exec_id != tsk-&amp;gt;parent_exec_id))&lt;br /&gt;844                 tsk-&amp;gt;exit_signal = SIGCHLD;&lt;br /&gt;845 &lt;br /&gt;846         signal = tracehook_notify_death(tsk, &amp;cookie, group_dead);&lt;br /&gt;847         if (signal &amp;gt;= 0)&lt;br /&gt;848                 signal = do_notify_parent(tsk, signal);&lt;br /&gt;849 &lt;br /&gt;850         tsk-&amp;gt;exit_state = signal == DEATH_REAP ? EXIT_DEAD : EXIT_ZOMBIE;&lt;br /&gt;851 &lt;br /&gt;852         /* mt-exec, de_thread() is waiting for us */&lt;br /&gt;853         if (thread_group_leader(tsk) &amp;&amp;&lt;br /&gt;854             tsk-&amp;gt;signal-&amp;gt;group_exit_task &amp;&amp;&lt;br /&gt;855             tsk-&amp;gt;signal-&amp;gt;notify_count &amp;lt; 0)&lt;br /&gt;856                 wake_up_process(tsk-&amp;gt;signal-&amp;gt;group_exit_task);&lt;br /&gt;857 &lt;br /&gt;858         write_unlock_irq(&amp;tasklist_lock);&lt;br /&gt;859 &lt;br /&gt;860         tracehook_report_death(tsk, signal, cookie, group_dead);&lt;br /&gt;861 &lt;br /&gt;862         /* If the process is dead, release it - nobody will wait for it */&lt;br /&gt;863         if (signal == DEATH_REAP)&lt;br /&gt;864                 release_task(tsk);&lt;br /&gt;865 }&lt;br /&gt;&lt;br /&gt;forget_original_parent() 先给自己的孩子找养父，然后把自己的孩子都过继给这个养父。&lt;br /&gt;&lt;br /&gt;do_exit() -&amp;gt; exit_notify() -&amp;gt; forget_original_parent()&lt;br /&gt;&lt;br /&gt;769 static void forget_original_parent(struct task_struct *father)&lt;br /&gt;770 {&lt;br /&gt;771         struct task_struct *p, *n, *reaper;&lt;br /&gt;772         LIST_HEAD(dead_children);&lt;br /&gt;773 &lt;br /&gt;774         exit_ptrace(father);&lt;br /&gt;775 &lt;br /&gt;776         write_lock_irq(&amp;tasklist_lock);&lt;br /&gt;777         reaper = find_new_reaper(father);&lt;br /&gt;778 &lt;br /&gt;779         list_for_each_entry_safe(p, n, &amp;father-&amp;gt;children, sibling) {&lt;br /&gt;780                 struct task_struct *t = p;&lt;br /&gt;781                 do {&lt;br /&gt;782                         t-&amp;gt;real_parent = reaper;&lt;br /&gt;783                         if (t-&amp;gt;parent == father) {&lt;br /&gt;784                                 BUG_ON(task_ptrace(t));&lt;br /&gt;785                                 t-&amp;gt;parent = t-&amp;gt;real_parent;&lt;br /&gt;786                         }&lt;br /&gt;787                         if (t-&amp;gt;pdeath_signal)&lt;br /&gt;788                                 group_send_sig_info(t-&amp;gt;pdeath_signal,&lt;br /&gt;789                                                     SEND_SIG_NOINFO, t);&lt;br /&gt;790                 } while_each_thread(p, t);&lt;br /&gt;791                 reparent_leader(father, p, &amp;dead_children);&lt;br /&gt;792         }&lt;br /&gt;793         write_unlock_irq(&amp;tasklist_lock);&lt;br /&gt;794 &lt;br /&gt;795         BUG_ON(!list_empty(&amp;father-&amp;gt;children));&lt;br /&gt;796 &lt;br /&gt;797         list_for_each_entry_safe(p, n, &amp;dead_children, sibling) {&lt;br /&gt;798                 list_del_init(&amp;p-&amp;gt;sibling);&lt;br /&gt;799                 release_task(p);&lt;br /&gt;800         }&lt;br /&gt;801 }&lt;br /&gt;&lt;br /&gt;其中 find_new_reaper() 的函数注释说的很明白:&lt;br /&gt;/*&lt;br /&gt; * When we die, we re-parent all our children.&lt;br /&gt; * Try to give them to another thread in our thread&lt;br /&gt; * group, and if no such member exists, give it to&lt;br /&gt; * the child reaper process (ie "init") in our pid&lt;br /&gt; * space.&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;do_exit() -&amp;gt; exit_notify() -&amp;gt; tracehook_notify_death()&lt;br /&gt;&lt;br /&gt;507 #define DEATH_REAP                      -1&lt;br /&gt;508 #define DEATH_DELAYED_GROUP_LEADER      -2&lt;br /&gt;509 &lt;br /&gt;510 /**&lt;br /&gt;511  * tracehook_notify_death - task is dead, ready to notify parent&lt;br /&gt;512  * @task:               @current task now exiting&lt;br /&gt;513  * @death_cookie:       value to pass to tracehook_report_death()&lt;br /&gt;514  * @group_dead:         nonzero if this was the last 
