听说python在CPU核心多的时候速度反而慢

从这儿看到的
A GIL Adventure (with a happy ending)

写了个测试, 的确是, 环境是python2.6.5 x86, Win7, 双核

D:\works\stars\server\utils>pbench.py
4.767000 seconds for a 5 x 100000 multithread test
2.997000 seconds for a 5 x 100000 single thread test
multithread overhead: 59.059059%
set process affinity // 把进程绑到一个核心上
3.755000 seconds for a 5 x 100000 multithread test
2.909000 seconds for a 5 x 100000 single thread test
multithread overhead: 29.082166%

D:\works\stars\server\utils>pbench.py
4.699000 seconds for a 5 x 100000 multithread test
2.914000 seconds for a 5 x 100000 single thread test
multithread overhead: 61.256000%
set process affinity
3.910000 seconds for a 5 x 100000 multithread test
3.004000 seconds for a 5 x 100000 single thread test
multithread overhead: 30.159774%

Linux下更可观, 环境是python2.6.6 x64, CentOS, 双路x四核

[xxx@xxx test]# ./dist/pbench
6.152628 seconds for a 5 x 100000 multithread test
4.913056 seconds for a 5 x 100000 single thread test
multithread overhead: 25.230169%
set process affinity to 1
5.032502 seconds for a 5 x 100000 multithread test
4.931799 seconds for a 5 x 100000 single thread test
multithread overhead: 2.041912%

[xxx@xxx test]# ./dist/pbench
6.162305 seconds for a 5 x 100000 multithread test
4.903964 seconds for a 5 x 100000 single thread test
multithread overhead: 25.659672%
set process affinity to 6
5.070047 seconds for a 5 x 100000 multithread test
5.042279 seconds for a 5 x 100000 single thread test
multithread overhead: 0.550706%

用了有一段时间Python, 遇到的第一个比较烦的问题, blocking raw_input

我有一个daemon程序, 运行中要求能接收用户输入命令退出, 也能超时退出

这两个事情都很简单, 前者:
daemon.start() # daemon在另一线程中运行
While True:
    cmd = raw_input()
    if cmd == ‘exit’:
        break
daemon.stop()

后者更简单了
daemon.start()
sleep(10)
daemon.stop

两个一起做
daemon.start()
While True:
    cmd = raw_input(1) # 检测一秒的input, 到时就退出
    if datetime.now() > exit_time:
        break
    elif cmd == ‘exit’:
        break
daemon.stop()

可是问题来了, raw_input不支持timeout, 它只能一直等到用户有输入为止, 彻底的blocking操作

搜索了一下发现不少人有这个困扰, 比如这个:
http://www.gossamer-threads.com/lists/python/dev/791714
在*nix下很简单, 用select等到stdin有输入为止, 而select是可以timeout的, 可是Windows下的select只能在socket上工作, stdin不行

类似的还有个用signal的解决方法, 不过兼容性就更差了

这里有个办法在Windows上调用msvcrt来实现non blocking input
http://bytes.com/topic/python/answers/46473-non-blocking-raw_input
可是看起来就很丑…

换条路, 分两个线程做, 一个线程里面sleep等超时, 另一个线程里面raw_input, 超时了就把raw_input线程杀掉, 可是python里面不能随便杀掉线程…

后来因为时间紧迫, 用了一个很丑的方案: 超时之后, 用ctypes直接调用TerminateProcess结束进程, 也就杀死了raw_input, 反正当时只在Windows下运行

可是最近要移植Linux, TerminateProcess肯定是不能用了, 试了一下用sys.exit()退不掉, 试验了一下是因为我在主线程里raw_input, 另一线程里超时sys.exit(), 这在Windows下ok, 在Linux下sys.exit()只会退掉超时那个线程, 影响不到主线程, 如果反过来在另一线程里raw_input, 在主线程里超时sys.exit(), Linux下就能正常结束掉

总之是要改, 还是想改得不那么丑陋, 找来找去突然发现threading.Thread有一个daemon属性:
http://docs.python.org/library/threading.html#threading.Thread.daemon
The entire Python program exits when no alive non-daemon threads are left.
这话说得真够绕的…

这下清爽了, 不用任何平台相关的花招就可以搞定:
from time import sleep
from threading import Thread, Event

e = Event()

def read_loop():
        while True:
                print ‘type something:’,
                a = raw_input().strip()
                if a == ‘exit’:
                        e.set() # 设置Event让主线程退出
                        break
                else:
                        print ‘you typed:’ + a

t = Thread(target = read_loop)
t.daemon = True # 关键, 不设这个的话超时之后read_loop线程还在, 进程退不掉
t.start()

e.wait(10)

if e.is_set():
        print ‘you typed exit’
else:
        print ‘time out’

对于某些糟糕

Black 15:24:30
用python 解析二进制文件咋办?

Black 15:24:37
read之后一个字节一个字节读?

Black 15:24:43
有没有啥readint啥的

JimmyZ 15:26:26
from struct import unpack

Black 15:29:12
为毛我依稀看到了fuck的字样

Knight and Day

很欢乐, Miller就是无敌就是自信, 上次见Tom Cruise跟Cameron Diaz一起还是香草的天空

 
Miller: Nobody follow us or I kill myself and then her!
我先杀了我自己, 然后…(怎么听着这么耳熟

 
June: (因为被下了吐真剂想啥说啥)I think I feel like having sex
(喘气)I think we’d have really great sex
Miller: (迟疑, 转向June)Did they give you something?
June: Uh-huh

附近竟然有个不错的飞场

昨天折腾了四个小时, 换了号称Micro级至尊的斜盘舵机DS95, 尾舵机换了8910, 之前好几次擦地有点磨损的尾桨也换了

今天中午下楼悬停, 不一会儿有个好心路人告诉我不远有个小公园给指了路

其实只有一百多米远, 一直不知道, 真不错, 有草坪, 而且比较大, 终于可以把一些以前楼下空地不敢做的动作从只能模拟器练放到真机上练

两个电的时间就从以前只敢对尾悬停偶尔对侧迅速进步到对头悬停, 慢速自旋悬停, 前飞航线, 还小试了一把圆周航线

之前的摆尾问题也解决了, 不知道是8910威还是新尾桨的功效, 不过总之解决就好, DS95的话, 我的水平还感觉不出区别

某科学的超电磁炮 之超电磁炮威力考证

超电磁炮的硬币射出速度是3倍音速以上, 按照漫画, 能力测定时的参数是:

炮弹初速 1030m/s
连发能力 8发/min
射程是50m

来看看著名步枪AK-47的现代(说是现代, 其实已经是1974年的老东西了)改进型AK-74的参数(取自维基百科):

枪口初速 900m/s
射速 600发/min
有效射程 600m

根据初中物理知识, 对于动能弹, 其能量 = m*v^2, 从初速来看, 比步枪初速高不了多少, 质量上硬币肯定比步枪子弹小, 总体来说应该跟步枪子弹同一量级, 一击轰翻一辆车神马的那根本不可能嘛

连发能力完败给AK

射程只有50m, 关于这一点, 漫画的解释是, 因为高速, 与空气摩擦熔掉了. 喂, 我说这点速度根本就不可能的吧… 谁听过步枪子弹会跟空气摩擦熔融的? 只听过航天器的返回舱会因大气磨擦而损耗, 来查一下, 阿波罗指令舱在大气层中的速度是, 呃, 30倍音速

变形金刚2(真人电影版)里美国海军的电磁炮拥有超视距一击击退大力神的威力, 现实中这玩意还没有实际部署, 至少公开的资料上看还没有, 不过按照美国海军公布的资料, 其08年试射的电磁轨道炮的炮口速是2520m/s, 约7.4倍音速

不管怎么说电磁炮的速度设定实在是太低了, 河马你需要一个军事控做顾问-_,-

Sex and the City (2008)

一个眼花把Sex and the City 2误当成Sin City 2给下回来了, 查了下评价还不错, 于是把前一部补了下, 还不错, 冷笑话很多

Samantha Jones: The good ones screw you, the bad ones screw you, and the rest don’t know how to screw you.

Carrie Bradshaw: What makes you think something bad is gonna happen?
Charlotte York: Because! Nobody gets everything they want! Look at you, look at Miranda. You’re good people and you two both got shafted. I’m so happy and… something bad is going to happen.
Carrie Bradshaw: Sweetie, you shit your pants this year. I think you’re done.

不过没有Meg Ryan的The Women好看

Phoebe in Wonderland

Phoebe in Wonderland (2008)

Phoebe: Why’d she take off her dress? If I had a dress like that, I’d never take it off.

女主Ella FanningDakota Fanning的妹妹, 长挺像的

联想你是有多讨厌DVI

今天又当好人修电脑去了, 略过

注意到一件有趣的事

那是一台联想ThinkCentre M8000t, 显卡是DVI/DP双接口, 注意, 没有VGA

联想配了一根DVI转VGA转接线接到显示器的VGA口上

那个显示器是有DVI接口的

关于DNS设置的建议

国内ISP的DNS经常不稳定, 于是我经常都用OpenDNS, 后来又改用Google DNS, 但是访问国内某些网站会慢, 因为ISP CDN会失效

虽然dnsmasq可以手动设置对某些域名使用指定的DNS服务器, 但是一个个手动加似乎很烦, 而且不是很全面

在这儿看到个好主意, 按Alexa排名找出中国前100域名
http://code.google.com/p/autoddvpn/wiki/DNSMasq

这样基本就足够了

还有个小问题是我的路由器刷的是Tomato固件, 这个设置太长写不进去…
看了一下dnsmasq的man page, 有个conf-dir参数
于是启用tomato的jffs, ssh上去建立目录/jffs/dnsmasq.conf/, 所有配置都写到那里
然后在tomato的dnsmasq custom configuration里写上conf-dir=/jffs/dnsmasq.conf/搞定