2011/11

勾搭上一个姑娘……

遇到过那么多不靠谱的,总算遇到一个靠谱的姑娘了。

和姑娘是在大理认识的,算是艳遇。姑娘不漂亮,但是很真实,也很彪悍,走南闯北,去过的地方不比我少。

相爱容易相处难,很多时候,爱情不只是要情投意合,更要经得起时间的考验。身边错过一个又一个,留下的这个才是真正属于我的。

在大理这个地方谈个恋爱多好啊!来到这之后的每一天都是大晴天,冬天一起坐在屋顶上懒懒地晒着太阳多舒服啊!我跟姑娘说,以后每年夏天来大理避暑,冬天就来大理过冬……这走走来来之间,大理就是我们断不了的想念!

又一个宏技巧

(本文为《C语言编程艺术》的一部分。)

这个技巧是从 Nick Bowler 的一封邮件中看来的,非常有意思,分享一下。

情况是这样的:在 Linux 内核中,有一个函数 kmap_atomic(),它之前带两个参数,而现在,它的第二个参数已经名存实亡了,可以直接去掉。所以问题就出来了,如何警告使用 kmap_atomic() 的人带有两个参数的形式是过时的?换句话说,怎么才能在用两个参数调用 kmap_atomic() 时发出警告而用一个参数调用时就没有警告?

所以下面的技巧就出来了。

[c]

define PASTE(a, b) a ## b

define PASTE2(a, b) PASTE(a, b)

define NARG_(_2, _1, n, …) n

define NARG(…) NARG(_VA_ARGS, 2, 1, :)

static inline void kmap_atomic(struct page page)
{
return __kmap_atomic(page);
}

static inline void __deprecated kmap_atomic_deprecated(struct page page,
enum km_type km)
{
return kmap_atomic(page);
}

define kmapatomic1(…) kmapatomic(__VA_ARGS)

define kmapatomic2(…) kmapatomic_deprecated(__VA_ARGS)

define kmapatomic(…) PASTE2(kmapatomic, NARG(VA_ARGS)(__VA_ARGS))

[/c]

这里最精妙的地方当属 NARGS 这个宏的定义,它通过参数个数来决定返回值,进而通过 PASTE2 来选择是 kmap_atomic1,还是 kmap_atomic2,而后者是过期的。如果用户用了两个参数,他就会得到类似下面的编译警告:

drivers/block/drbd/drbd_bitmap.c:973:3: warning: ‘kmap_atomic_deprecated’ is deprecated (declared at /home/wangcong/linux-2.6/include/linux/highmem.h:124)

非常聪明,不是吗? :)

/ 和 //

看下面这个的例子:

[wangcong@cr0 ~]$ cd /

[wangcong@cr0 /]$ pwd

/

[wangcong@cr0 /]$ cd //

[wangcong@cr0 //]$ pwd

//

[wangcong@cr0 //]$ cd ///

[wangcong@cr0 /]$ pwd

/

[wangcong@cr0 /]$ cd ////

[wangcong@cr0 /]$ pwd

/

其实 POSIX 规范里有讲到,Pathname Resolution

A pathname consisting of a single slash shall resolve to the root directory of the process. A null pathname shall not be successfully resolved. A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.
大多数实现,包括 bash,都是把 // 当 / 来处理,但是仍然显示 //。但 zsh 不是,zsh 把 // 当 / 处理并显示。

ping 的 mdev 值

在运行 ping 命令的时候,里面有一项输出叫 mdev,如下所示:

~% ping www.google.pt

PING www.l.google.com (72.14.203.103) 56(84) bytes of data.

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=1 ttl=50 time=84.1 ms

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=2 ttl=50 time=83.0 ms

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=3 ttl=50 time=85.5 ms

^C

—- www.l.google.com ping statistics —-

3 packets transmitted, 3 received, 0% packet loss, time 2001ms

rtt min/avg/max/mdev = 83.019/84.227/85.506/1.016 ms

它是什么意思呢? ping 的手册中并没有提到。我们不妨看一下 ping 的源代码,见 ping_common.c:

tsum += triptime;
tsum2 += (long long)triptime * (long long)triptime

以及

tsum /= nreceived + nrepeats;
tsum2 /= nreceived + nrepeats;
tmdev = llsqrt(tsum2 - tsum * tsum);

所以我们可以得出:

mdev = SQRT(SUM(RTT*RTT) / N - (SUM(RTT)/N)^2)

也就是这个平均偏差的公式:

所以 mdev 就是 Mean Deviation 的缩写,它表示这些 ICMP 包的 RTT 偏离平均值的程度,这个值越大说明你的网速越不稳定。

布拉格之行

因为开会的原因去了一趟捷克,顺便在那里玩了一圈。阔别三年,终于回到欧洲了,最遗憾的是这次因为签证的原因没机会到葡萄牙看望以前的同事了。:-( 不过,在布拉格开会期间遇到了 Fengguang Wu 和 Ying Han,就约着一起出去玩。

布拉格绝对一个是典型的欧洲城市,有很多欧式风格的教堂、城堡,当然啦,还有大名鼎鼎的布拉格广场和查理大桥。

到了你会发现,这几个景点每天都是游客如织,即便秋天已经不是去捷克的最佳季节。所以,那首歌里唱的“布拉格黄昏的无人的广场”都是骗人的!黄昏的时候布拉格广场人山人海!

虽然说夏天是来捷克旅游的最佳季节,但我认为秋天的布拉格也很不错,可以看到各种各样的颜色。

离开布拉格,在捷克南波西米亚地区,靠近奥地利的地方,有一个非常出名的小镇,叫克鲁姆洛夫(Český Krumlov)。这里被称为“捷克的丽江”,确实和丽江风格类似,不过它比丽江要小得多,人也相对不多。那里除了那个闻名的城堡,还有一个非常好看的地方,就是瓦尔塔瓦河拐弯处。整个小镇美妙绝伦,天一放晴,感觉像是步入了童话世界。

在克鲁姆洛夫的时候住青旅,遇到一个日本姑娘,第二天和她一起逛了逛小镇,海阔天空地聊了很多,发现日本人真心爽,去世界上好多地方都不需要签证,包括中国!我就不好意思对比中国的了。

在捷克西部,也有一个知名的小镇,叫 Karlovy Vary。这个小镇以温泉而出名,所以那里有很多慕名而来泡温泉的人,但景色一般。我去那儿的时候还尝了尝免费的温泉,真的很难喝,还不如白开水呢。

这里一个有意思的插曲是,中午吃饭的时候我无意间着走到一家小店,老板是一位非常和蔼可亲的捷克大叔。他会汉语哦,而且还能说不少呢!和他聊了聊才知道,原来他之前是在捷克驻北京大使馆工作!说完,还一直用汉语说“建国门、建国门……”。临走之前,大叔给我要几个人民币硬币,我索性掏出一把零钱来都给他了。大叔问我今晚要不是住这,我说可惜我要回布拉格了。

下面这个就是他的店的广告,如果你有机会去 Karlovy Vary 的话,记得去这个大叔店里面坐坐哦!

住宿推荐:

Český Krumlov, Hostel99, http://www.hostel99.cz
Prague, Hostel ELF, http://www.hostelelf.com