Shell's Home

python中调用C的几种方法

May 22, 2012 - 1 minute read - Comments

引言 别废话了,我觉得这都应当是常识的。除去最后几种包装框架,剩下都是基本知识问题。即使不知道怎么做,也应该知道有这种方法。所谓经验,很多时候不是把知识装脑子里,而是把索引装内存,数据丢硬盘。 C模块 最基本的方法,直接写个C模块。具体很长,你去找python-doc,看“Extending and Embedding”这章,全看完就差不多了。如果没空,看几个例子就上也可以。 优点:基本没有,写起来很麻烦,要维护额外的C代码,还有交叉版本固定,跟随C升级等等麻烦。唯一的优点,就是这是唯一一个“绝对没有问题”的方法,而且没有额外依赖。如果下面几个路子全出了问题,就用C模块吧。 ctypes 去看python-doc的ctypes模块。本质上是提供一个C模块,去载入和使用其他模块。 优点:写起来很方便,修改便捷,而且跨各个python实现。 缺点:只能调用动态库,对静态库没啥办法。某些复杂数据类型的转换很麻烦,据说有时还有效率问题。 swig 自己找,一个叫做swig的项目,目标是制作C语言的各种平台包装。实现上看,会生成一个动态库和一个py。 优点:跨平台多。如果你的C代码不仅是python需要调用,还有其他语言(例如php),那么swig用起来很舒服。 缺点:编译时引入额外依赖,而且调用范式也是受限的。不过别担心,一般你也用不到范围以外的范式。 boost.python boost的自带库,只能用于C++。 优点:对C++的支持是极好的。 缺点:要依赖boost这么个坑爹玩意,摔。 Pyrex 我知道douban的python-libmemcached是使用这个来包装的,不过没用过,不是很清楚。

语言的效率差异2

May 18, 2012 - 4 minute read - Comments

问题 为了更深入的测试语言,我做了一个经典问题——24点。 这个问题主要是测试递归,循环效率,还有数组和树的复制性能。 为了简化问题,方便测试,我的问题是这样描述的: 有一个数组,里面有多个正整数。有一个操作数组,其中每个都是双目操作符。找出以两者构成算式,其值等于给定值的所有表达式组合。 要求不得遗漏,可以有少量重复。例如可交换算符的交换同构暂不做排重。 实际运行的时候,取+-*/和3 4 6 8,运行100次,查看时间消耗。正确的单次输出结果应当是这样的。 (((8 + 4) / 3) * 6) = 24 (6 / (3 / (8 + 4))) = 24 (((8 + 4) * 6) / 3) = 24 (((8 / 4) + 6) * 3) = 24 (((8 - 6) * 3) * 4) = 24 (((8 - 6) * 4) * 3) = 24 (((3 * 4) - 8) * 6) = 24 ((8 - (6 / 3)) * 4) = 24 (((4 + 8) / 3) * 6) = 24 (6 / (3 / (4 + 8))) = 24 (((4 + 8) * 6) / 3) = 24 (((8 / 4) + 6) * 3) = 24 (((4 * 3) - 8) * 6) = 24 (((8 - 6) * 3) * 4) = 24 (((8 - 6) * 4) * 3) = 24 ((8 - (6 / 3)) * 4) = 24 python python的解很复杂,长达31行,以下是我写的解。当然,还有更简单的版本,我可以用eval来干这个事情,代码只有24行,但是确实给人很evil的感觉。 from itertools import combinations class opt(object): def __init__(self, name, func, ex=True): self.name, self.func, self.exchangable = name, func, ex def __str__(self): return self.name def __call__(self, l, r): return self.func(l, r) def fmt(self, l, r): return '(%s %s %s)' % (fmt_exp(l), str(self), fmt_exp(r)) def eval_exp(e): if not isinstance(e, tuple): return e try: return e[0](eval_exp(e[1]), eval_exp(e[2])) except: return None def fmt_exp(e): return e[0].fmt(e[1], e[2]) if isinstance(e, tuple) else str(e) def print_exp(e): print fmt_exp(e), eval_exp(e) def chkexp(target): def do_exp(e): if abs(eval_exp(e) - target) < 0.001: print fmt_exp(e), '=', target return do_exp def iter_all_exp(f, ops, ns, e=None): if not ns: return f(e) for r in set(ns): ns.remove(r) if e is None: iter_all_exp(f, ops, ns, r) else: for op in ops: iter_all_exp(f, ops, ns, (op, e, r)) if not op.exchangable: iter_all_exp(f, ops, ns, (op, r, e)) ns.append(r) opts = [ opt('+', lambda x, y: x+y), opt('-', lambda x, y: x-y, False), opt('*', lambda x, y: x*y), opt('/', lambda x, y: float(x)/y, False),] if __name__ == '__main__': for i in xrange(100): iter_all_exp(chkexp(24), opts, [3, 4, 6, 8]) 以下是100次的时间: real 0m2.259s user 0m2.248s sys 0m0.004s common lisp lisp来解这个问题简直是作弊,难怪被叫做人工智能语言。 (defun chkexp (target) (lambda (e) (if (equal (ignore-errors (eval e)) target) (print e)))) (defun exchangeable (op) (not (member op '(- /)))) (defun iter-all-exp (f ops ns &optional e) (cond ((not ns) (funcall f e)) ((not e) (dolist (r (remove-duplicates ns)) (iter-all-exp f ops (remove r ns :count 1) r))) (t (dolist (r (remove-duplicates ns)) (let ((nss (remove r ns :count 1))) (dolist (op ops) (iter-all-exp f ops nss `(,op ,e ,r)) (if (not (exchangeable op)) (iter-all-exp f ops nss `(,op ,r ,e))))))))) (iter-all-exp (chkexp 24) `(+ - * /) `(3 4 6 8)) 只有短短17行。原因在于,lisp本身的ast即是用数据结构表示的,因此根本不需要我做eval函数,也不需要画蛇添足的弄自定义算符,直接用系统算符上。显示,打印,都是现成的。需要写的只有主体逻辑。结果也很特别: (* (- (* 3 4) 8) 6) (* (- 8 (/ 6 3)) 4) (* (- (* 4 3) 8) 6) (* (/ (+ 4 8) 3) 6) (/ 6 (/ 3 (+ 4 8))) (/ (* (+ 4 8) 6) 3) (* (+ (/ 8 4) 6) 3) (* (- 8 (/ 6 3)) 4) (* (* (- 8 6) 3) 4) (* (* (- 8 6) 4) 3) (* (/ (+ 8 4) 3) 6) (/ 6 (/ 3 (+ 8 4))) (/ (* (+ 8 4) 6) 3) (* (+ (/ 8 4) 6) 3) (* (* (- 8 6) 3) 4) (* (* (- 8 6) 4) 3) 不但行数只有一半,速度也很让人吐血,比python快了近一倍,这是100次的结果。 Evaluation took: 1.379 seconds of real time 1.372086 seconds of total run time (1.372086 user, 0.000000 system) [ Run times consist of 0.012 seconds GC time, and 1.361 seconds non-GC time.

语言的效率差异1

May 14, 2012 - 2 minute read - Comments

问题 为了测试语言的效率,做一个正则解析。 预先说好,正则解析的问题是老板正在做的一个实际问题,我把其他和效率无关的部分去了。因此我接受“用法不正确”这样的反驳理由,但是不接受“这不是典型用例”的理由。我欢迎你指正我的用法错误,或者对语言不了解导致的效率低下,但是别来和我吵吵这种例子太特殊。另外,在调整代码和评估速度的时候,顺便注意一下代码行数。我知道用汇编逐行写和优化会很优秀,但是这对实际工作基本没有帮助。 问题是这样的: 有一个文本文件,每行两个数,要求解析出来这两个数。 我用python生成了数据,代码是这样的 with open(sys.argv[1], 'w') as fo: for i in xrange(500000): fo.write('%d %dn' % (i, random.randint(0, 10000))) 正则分析速率,是个典型的CPU密集操作。对于非编译型语言而言(这里的编译是指正则表达式的解析预编译,实际上除了lisp还真没有编译型的,即使是go也是现场拿到正则进行解析的),这主要是看正则库的实现效率。很多时候,语言的效率问题并不取决于语言本身,还取决于语言的库的实现。大部分情况下我们都不可能砍掉系统的库重新来一个,那还不如换一门语言。 python 我首先贴出python语言的解答。 reline = re.compile('(d+) (d+)') def main(): with open(sys.argv[1], 'r') as fi: for line in fi: reline.match(line).groups() 这是性能 real 0m0.466s user 0m0.436s sys 0m0.012s common lisp 我找了N个正则包,实际能用的只有ppcre。有些包号称很快,实际测试下来还不如ppcre。 (require :cl-ppcre) (defun grepfile (filename) (let* ((cl-ppcre:*use-bmh-matchers* t) (cl-ppcre:*regex-char-code-limit* 256) (scanner (cl-ppcre:create-scanner "d+ d+"))) (with-open-file (in filename) (loop for line = (read-line in nil) while line do (cl-ppcre:split scanner line))))) 代码在slime里面测试(time (grepfile “data.dat”)),下面是结果 CL-USER> (time (main)) Evaluation took: 0.398 seconds of real time 0.392025 seconds of total run time (0.384024 user, 0.008001 system) [ Run times consist of 0.016 seconds GC time, and 0.377 seconds non-GC time.

新闻和八卦和概率聚集

May 11, 2012 - 1 minute read - Comments

新闻和八卦有个共同点,就是会扭曲我们常规的概率体验,例如:今天摔了一架飞机。我们的结论往往是,飞机好危险。然而,世界上有很多没问题的飞机,这个你是不会从新闻和八卦里面听到的。因此,以这些东西为基础得出的结论,往往是错的。 从这点说开去,其实我们会发现很多东西都不可靠。首先说八卦。八卦之不可靠是全世界皆知的,要是有人神神秘秘和你说个事情,要么是一点不着边的瞎猜,要么就是一枪命中的内幕。可惜的是,到底是哪个,在事先完全无法分辨。香农说,信息就是减少不确定性,从这点来说,这些八卦里面的信息量是负数——本来一个事情挺明白,八卦一传,搞不好当事人都不明白是怎么回事了。 其次我们再说新闻,新闻倒是有信息量,但是新闻的不可靠也是人尽皆知。中国的文艺宣传理论就不去说了,老美也经常骂,大新闻集团只挑符合他们利益的说。不过幸好,人家新闻利益集团有好几个,岳飞打张飞之下,总算还有不少东西给披露出来。 最后,你的亲眼所见一定是真么?我在以前的一篇blog里面说过,我对问题的分析是偏颇的,因为我做不到随机取样。我周围的朋友,一定是具备某个特性/符合某个范式的。例如熟悉电脑,受良好教育的城市青年,中国人,这些总是没办法的事情。如果以此为样本来分析相关问题,相信一定会南辕北辙。例如你以我的gtalk和twitter好友来分析python和emacs用户的比例,那一定是高的异乎寻常。这是当然的,我本来就是以python和emacs作为自己的标签,无论是朋友也好,会fo我的人也好,多半是此道同好。以此类推,若是你不仔细分析,即使以亲眼所见,也未必能得到结论。

全部和谐音程表(泛音表)

May 10, 2012 - 1 minute read - Comments

>>> for i in [(i, j, 12 * math.log(float(j)/i, 2)) for i, j in itertools.permutations([1,2,3,4,5,6], 2) if i < j]: print i ... (1, 2, 12.0) (1, 3, 19.019550008653876) (1, 4, 24.0) (1, 5, 27.863137138648348) (1, 6, 31.019550008653873) (2, 3, 7.019550008653875) (2, 4, 12.0) (2, 5, 15.863137138648348) (2, 6, 19.019550008653876) (3, 4, 4.980449991346124) (3, 5, 8.843587129994475) (3, 6, 12.0) (4, 5, 3.863137138648348) (4, 6, 7.019550008653875) (5, 6, 3.1564128700055254)

论医

May 9, 2012 - 1 minute read - Comments

医生的道德标准 要摆正医患关系,首先就必须将医生的道德标准降下来,从“白求恩精神”,降低到一般人标准。 为什么?有一则故事,叫做“子贡赎人”,挺有名的,大家可以自查。跳过故事本身,我直接说其中的观点: 如果将道德标准提高到没有人能够接受的地步,就不会有人照做了。 类似,大家都是人,为什么让别人去遵循“白求恩精神”,或者其他变态的精神,而让自己能够得利呢?拥有这种精神的毕竟是少数。以这个为标准要求多数人的结果,就是没有人能够成为医生。 医生的标准,只要能够诚实的提供服务就好了。动辄就拿奉献说事,实则是用大帽子压人,和文革无异。 当然,现今最主要的问题,是以白求恩精神要求医生的同时,连诚实服务都贯彻不下去。这种动辄涉及人命的事情上不公开透明是会出人命的。只要有一小撮是贯彻不下去的,那病人就会连剩下的医生一并怀疑,然后杀医生的戏码就会层出不穷。 貌似要立法阻止杀医什么的,其实我说,这也就是对纯粹的医闹管用,真的爆上新闻的,多半不会是医闹。道理很简单,医闹的目的是拿钱,耍赖撒泼软语哀求的目的都是拿钱而不是报仇。就算他再和医生横眉竖眼,也不会往死里下手——真的往死里整的,多半是豁出一条命的家伙。人不畏死,奈何以死惧之。解决这个问题的最好途径不是阻拦,而是有个心平气和能让他解决问题的途径。 不实施抢救的道德标准 我认为,以下两种情况下,不实施抢救不应当受到责难。 病人死亡。 病人不可避免的向死亡发展,其中会为本人或家属带来极大痛苦。 医疗会耗尽社会的剩余资源 我觉得这是不言自明的。人类社会从原始社会仅够自己温饱,发展到目前的状态。实则目前一个人的工作供养数人足矣。或者换个表达方式,全球所有人所需的食物/衣物/住房等资源,并不需要所有的人类进行生产。若非如此,贫困救助体系和养老体系都没有发展的前提。多余的人产生的物资,即是社会的剩余资源。 社会目前的剩余资源,必然会有一个出口。一方面,第三产业,娱乐业,都是基于剩余资源的。也可以看作,从事生产的人为他们提供食粮,而他们为从事生产的人带来娱乐。而另一方面,科技发展,医疗和医疗技术发展,也是基于这些资源的。 随着科技发展,人类的剩余资源冗余度会越来越大。人类需要的必需品只需要更少的人进行生产,更多的人会投身非直接产生必需品的行业。在这种情况下,我更希望他们参与医疗和科技发展。并不是说娱乐业不好,或者不需要。只是科技和医疗能够带给人更好的生活——我是这么相信的。

升调降调的规则

May 7, 2012 - 1 minute read - Comments

为什么C加一个升调变成G? 这个要从大调式讲起。 大调式是以大三度为基础构建的调式,主音到中音为大三度,中音到属音为小三度,两者构成大三和弦。主音到属音为纯五度,属音到主音为纯四度,大调式的三个基础音之间,都是和谐音程关系。以C大调而言,就是do mi so。 好吧,C大调之所以叫做C大调,是因为以中音C为do。那么G大调呢?以中音G为do?对的,问题是,C大调的所有音,是否能够不做任何变化的构成G大调的音? 这是不可能的,C大调的音不做变化唯一能够构成的只有a小调。G大调一定需要对C大调的音做升降的。 为什么?因为C大调的音程关系是全全半全全全半,这个在小学就教了。通过这个,你可以数出上面说的三个纯音关系。当我们位移到G=do的时候,你会发现,不做变化的话,音程就变成了全全半全全半全,这就糟了。所以,需要对C调的fa(即F)升半个音,来回复大调调式。 常识上我们知道,12平均率是对称关系,所以上述过程可以运用数学归纳法作用于整个中音音阶。即,每个大调可以通过升该调中的fa半个音,变成另一个大调。后者刚刚好比前者高一个纯五度。 降调关系亦然,可以类比。 小调关系亦然,不过小调使用全半全全半全全作为结构,主音到中音为小三度,中音到属音为大三度,两者构成小三和弦。主音到属音为纯五度,属音到主音为纯四度,小调式的三个基础音之间,也都是和谐音程关系。 稍微数一下就知道,小调式上的所有音,可以构成比自己高小三度的大调,两者称为关系大调和关系小调。 虽然音是一样的,然而主音中音属音的位置完全不同,因此调式色彩完全不同。

关于翻墙服务几句

May 4, 2012 - 1 minute read - Comments

目前有很多服务,其实我们都是按照非正规用法在用的。例如github,看上去像是个源码托管服务,我们拿来当blog用。GAE,看上去像是个代码托管服务,我们当翻墙工具用。空间,常规都是发布应用的,我们也拿来翻墙。 对服务的非正规用法,我们首先把这个命题分几个类。一类是服务本身没有对用法做出特殊假定,但是你的用法和传统用法相违背,例如VPS传统是作为私有主机用的,用于发布网站。但是天朝人民经常用VPS当作云存储,或者是VPN。作为这类用途,我觉得是没有任何问题的,服务商本身就没有限定你的应用类型。 第二类,是服务商默许或者半鼓励你作为特殊用途应用。例如github并不反对你用他作为blog。这也没问题。 第三类,服务商明确反对的用途。例如利用空间来翻墙。一来ssh流量并不计入你的流量限额中,二来长期使用空间翻墙会导致空间的服务器地址在中国被封。前者影响成本,后者影响销售。因此,很多空间商都封锁了ssh的跳板功能,例如DreamHost。 也许有人会骂,空间商为什么要阻止ssh,这是对自由人权的破坏什么的。我觉得这压根是骂错人了。如果你无法自由浏览你想要浏览的网页,你需要骂的是阻止你访问的人,而不是别人。空间商既没有封你,也不是帮凶。通过对人有害的方法获得自己想要的利益,别人阻止你还骂人,这是流氓嘴脸。 第四类,服务商没有明确回应,他们可能对此一无所知。这种情况最复杂,也最值得讨论。 无论空间商默许还是反对,我们都可以看作是一个附加合同。这种事情你同意就接着用,不同意就换家人,市场经济大家好聚好散。但是服务商没有明确回应,那么事情就比较暧昧。我倾向于将事情分为两个阶段,或者类型。一类是影响较小,或者刚刚出现,服务商有理由不知道。这种阶段下,该怎么用就怎么用。直到服务商有表态为止。另一类是我们有理由相信服务商知道这类用法。在这种阶段下,你不妨参照第二类。 当然,这里顺便说另外一个话题,就是很多人对翻墙的要求是——免费。 我去阿,你在中国网络上玩多了,啥都要免费,有没有写信给电信要求宽带接入免费阿。你要是真没钱,要么就不用,要么就学学怎么让自己出去。 天下的特权有几类的,一种是你通过努力来获得某种特权,一种是你付钱让别人帮你获得这种特权,一种是左求右拜,借到某种特权。这特权还不稳固,有点问题就让人收了回去,因此不得不小心翼翼,缩着尾巴做人。且不提现实中有个头痛脑热,行政手续,求爷爷告奶奶的诸多无奈。那毕竟很多时候还是不得以而为之。网络上凡是有点大小P事,全是“360度冰天雪地裸体跪求”,就这种人还自诩为“不食嗟来之食”之后,实在让人叹息。 墙的存在意义,就是要“拦截大多数”。要稳定翻墙,基本就两种途径。一者是牛,自己付出辛苦,学会了整个过程,从而翻墙出去。或者你付钱,弄到了翻墙帐号,从而翻墙出去,这也是一种。这两者都算的上少数,剩下的就是绝对的大多数。既不付钱,也不想付出辛苦,张口就求各种方法的人不知有没有想过,当某种方法会的人多了,墙自然就会把这种方法连根铲掉。法子不能用了,瞬间破口大骂给法子的人,不知道脑子里转的是什么逻辑——或者是,他们其实想过,只是: 在中国,只要考虑三天后的事情,三个月后的事情谁说的准呢。 在网络上求爷爷告奶奶也是一种辛苦阿。 ——我已经连叹息都发不出了。 最后一个话题,如果你的某种对服务的应用,对其他人会产生伤害怎么办?例如,你用某个空间翻墙,这个空间IP就可能被墙。你用GAE翻墙,GAE就会被墙。你在网站上发表很合理的言论,自己没事,站长进去了。 首先请允许我就最后一个例子向中国的有关部门表示无比的XXX。。。就这精确度还好意思指责人家老美的导弹? 我们先说最后一个。很多人往往鄙视中国的网站管理者,我写个无比正常的内容你都给我删了。实际上,在一切不正常都当作正常的国度,再正常的内容都可能是不正常的。我是挺同情网站的管理者的,删把,道义上挺站不住的,不删吧,自己进去了。某种意义上说,开网站是为了赚两个钱顺便提供娱乐的(当然,很多人是反过来的),而不是为你表达言论挺身而出的——真是这个目的开的网站现在站长的骨头都在长草了——从这个意义看,删,不是恶。如果你要指责,应当指责的是这个制度和产生这个制度的原因。 但是,我又要但是了,这也有个度。删本身不是恶,但是捕风捉影,删了不说,不删,偷偷让别人看不到,这就沦为不道德了。只是在中国,各种事情交错纠缠之下,人人皆提心吊胆提防别人,往往事情就会走了样。 这里插一个前两天的段子。魔都地铁是要安检的,大家知道。坐地铁的经常听说保安和你争执两句就躺地上装死讹钱的例子。前两天过地铁的时候,把包拿给保安检查。保安摸到我的饭盒,说,这是啥阿。我刚要说话,旁边保安示意放行,小声说,摸坏了你赔不起。 ——那地铁安检的结果就不言自明了。 因此,在层层把关的网络审查中,往往下层执行的东西和上层想的差了十万八千里。其距离大概就和客户心里的网站和项目经理笔下的网站和工程师手下的代码的区别差不多。 当然,即便结论如此,我还是管我自己。我的blog都是在自己的域名下面——结果被封,也是自己的选择。如果发到其他网站,能不能留,留多久,就看别人的意思了。 至于使用GAE翻墙的问题,我觉得适用于我们有理由相信服务商知道的情况。我相信Google一定知道上面有人放什么网站,做翻墙用途。既然他没有反对,我们可以看作是他默许。

dvc和vc简评

May 3, 2012 - 1 minute read - Comments

我有必要换git么 实话说,这得分干吗。目前的推荐是,如果是企业级项目,对权限要求比较严格,你必须用svn。如果是普通项目,你可以尝试使用git,但是这并不表示git是最适合你项目的。有的时候svn比git合用的多。 svn是什么模式 svn的核心思路是,取出,修改,提交,合并。即,你从核心库中取得数据,修改,然后提交上去。如果有两个一样的修改,那么要求你进行合并。当然,svn工具会首先尝试自动合并,然后再让你手工干。但即使如此,合并的时候还是很费力。 svn的模式很容易理解,然而在使用中却有两个实际缺陷。 保存数据的唯一方式就是提交,而提交是不可撤销的。 必须连接核心库使用。 第一点问题,就是说,如果你希望暂时保存一下当前的修改状态,然后进行某个测试性修改。如果失败,退回当前。抱歉,做不到。你的提交一定会进入svn库。虽然你可以退回到你提交前的版本,但是很麻烦,而且版本记录不会消失。而第二个问题更加致命。如果在网络不稳定/没网络的时候,还干不干活了? 因此,svn的设计模式并不鼓励你提交。当你有修改的时候,你必须保持修改的状态,直到某个稳定的状态。你需要检查代码是基本可用的,然后才应当提交。svn提交有个基础原则,不能塞住head,讲的就是这个。 所以有了hg hg正是为了解决上述问题而出现的。hg实际上是用python实现的,解决上两个问题的svn。 hg拥有本地版本库,这解决了离线模式。至于暂存性提交,你可以在本地随便提交。只要不提交到核心库上,就不会导致塞住。如果你觉得本地库不行,可以直接重新co,而不进行push。 git和hg哪个好 锤子和扳手哪个好?我永远无法回答你这个问题,因为这两个的目标根本不同,因此根本没有可比性。同样,git和hg的工作流程和模式完全是两回事,因此不要问这个问题,没意义。 哦,那么git是 git的设计核心思路,是取出,分支,修改,提交,合并分支。git的分支是处理工作的利器。 要彻底理解git,你必须接受平行世界假定。假设世界并不是顺序发展的,由于你的选择不同,而会变成不同的几个分支。git可以让你在分支间自由穿越,并且让世界变成某个分支上的某个点的状态。你可以重新选择,产生一个不同的分支。当你需要时,可以对两个分支进行合并。如果两个分支从源头分开后,对世界的影响各自不同,那么合并就是自动的。 git的同步就是在同步这颗世界树。树扩展成什么样子和你在树的什么位置没有关系,因此fetch后如果不chechout,那么就不会应用最新的修改。 我没看出多大区别 实际是非常大的。有了平行世界假定,我可以正交的对一个源码做两件以上不同的事情。而在hg中,虽然也可以做两个不同的分支,然而却很难在两个分支间切换,从而使得切换到做另一件事情非常困难。这也导致了一个人实际上只能做一件事情,否则就无法将过程同时纳入vc管理,又满足正交。

首次bsp日记

May 2, 2012 - 1 minute read - Comments

第一次参加BSP,还不错拉。因为以前没参加过,所以等搞明白了这个是干吗的再和大家说。 BSP是bug squeeze party的简称,简单来说就是修错会。debian马上要发行7了,在此之前有很多的bug没有修复。其中有一种是RC bug,即运行就会出大问题的bug,或者干脆没法编译。无论哪个,都会导致这个包不能进入最新的发布。有些bug很麻烦,需要maintainer和author沟通,这个没有办法。但是有些问题解决起来很简单,只是因为后果很严重,作者又暂时没空处理,导致包无法进入stable,实在很无谓。BSP的目的,主要是以非维护者上传(non-maintainer upload)的方式修复这类bug。因为包不是自己的,所以礼貌上,只修复半个月以上的rc级别bug,其他的留给maintainer来处理。 BSP的主要目的,就是这么一个苦力会。没有挂名,最多只有一条changelog记录,还要大量寻找和修复bug。不过BSP相当重要,因为很多maintainer往往有一段一段的不活跃时间。这时候即使再简单的问题也不会处理。按照debian的规则,别人也不会帮他处理。除了BSP,很少有一批人会专门找这种简单的Bug来修正。如果没有BSP,debian stable发布的时候一做RC冻结,就要少掉很多有用的包。BSP更大的目的是,交流和传授debian打包和除错的经验,唤起人们的关注。也许在会后,如果有人看到一些简单bug,会使用nmu的方法给与修正。不过BSP到确实是有一个额外加成的好处——基本变成了签名会。昨天估计是中国大陆地区首次DD数量接近其他人数量,我一下弄到了5个签名,2个DD一个Ubuntu员工。加上原来就有的zigo签名,我就有3个DD签名了。 本地BSP是在thomas的公司举行,欧特家博士匹萨厂商赞助了我们两天的午餐——微波食品匹萨。第一天来的人比较多,很多都是纯新手,大概有20多人。Zigo倒是在网络上说会帮助新手,但是纯新手看到debian打包系统根本无从下手,所谓指导什么的也无从说起。很多人一天一个bug都修不掉,甚至都看不懂,很有挫折感,估计有不少有热情的人在第二天就这么默默退散了,第二天只来了15个左右。 我主要是以修复自己的问题为主,python-snappy和python-formalchemy都升级到了最高级,并且修复了自己以前打包的一个问题。至于RC bug么,我修了一个。两个包在python中命名冲突了,所以在debian中需要声明为conflicts。另外我评审了一下,最终还是决定关闭了python-libmemcached的ITP。虽然对douban很不好意思,还让他们修了一下。但是python-libmemcached依赖于libmemcached,而后者已经逐步升级到了1.0.X版本,但是douban为了稳定使用,是sticky在0.4版上的。因此当更新的debian发行时,实际上python-libmemcached和系统中的libmemcached不是一回事。因此,我不能依赖libmemcached的维护者,而是需要自己去维护后者——没办法,我就是怂了。python-libmemcached的爱用者,还是自己打包吧。我倒是可以公开打包文档。 另外,我在想是否要集合一批python/debian的用户,来做投票。例如,python的一个容器——flup,在debian中实际上已经orphon了。如果有足够的人投票,我愿意为flup做接手维护工作。不过目前debian下问下来的结果,大家对flup没什么太大兴趣。