为四川人民祈祷! www.onefoundation.cn
logo of kjam.org

eurasia and coroutines

上周末的CPyUG上海python聚会, 沈游侠又一次show了他的eurasia框架. 之后javaeye的robbin写博讨论, 然后被nicholasdsj在twitter上发问... 看起来超级热闹.

对于eurasia是不是有那么高的性能, 考虑到沈游侠在娱乐界的地位, 我也不敢随便评价. 总之希望明天会更好, 这也是我们写程序的每个人的美好愿景.

更大的收获还在于对问题的思考, 进程, 线程和协程, 本来就是完全不同的概念, 如今被混在了一起.

进程, 线程是操作系统的概念, 一个多任务操作系统必然有多进程. 线程是可选的, 好处是不同线程可以在进程内共享内存. 教科书都是这么介绍的, 只要操作系统不是那么老掉牙(DOS), 进程们可以同时运行啦.
但是不能忽略的事实是, 单核CPU在同一时间内只能执行一个指令, 那为什么说多任务呢? 仔细一想, 什么进程和线程只不过是CPU按照时间分配而已, 都是些内核玩的把戏.
那么, 按照时间分配是否适合服务器程序呢? 数据在到达网卡之前, 疯狂进程和线程切换只能是两个字: 白干. 不过, 想去掉进程这种玩意, 其他的服务你跑啦? mysql不用啦?
老老实实放弃线程, 或者换一种说法, 放弃系统提供的按照时间切换的线程, 实现自己线程.

OK, 就此打住, 我们再来看看协程

协程的定义可以查看高纳德的 The Art of Computer Programming 或者维基百科, 与协程相对的定义是子例程(应该就是子程序, 好经典的词汇, 让我们回到函数之前的年代)
(这里强调, 协程只是相对于子程序的一种编程概念, 但是到了stackless python中, 却变成了一种替代线程的产品了.)

说白了协程可以自己控制子程序(或者更加现代的说法: 函数)间的切换, 而不像 POSIX pthread 那样按照时间切换. 话说因为GIL的关系, Python的线程确实不敢恭维.
这样说来, 采用stackless python的eurasia的确可以省掉不少CPU资源, 单线程且没有加锁需求.
思路很对.

还有什么可以突破的?
poll和intrrupt模式, 用中文讲就是轮询和中断.
socket的一个相当通用的编程模式就是poll, 就是轮询, 显然不是什么高效的模式. 采用中断模式来驱动协程之间的切换一定会有助于性能的提高. epoll或者IOCP, 应该是已经被验证了的, 有效提高服务器效率的方式.

eurasia如果放在stackless+twisted上, 一定会增色不少.
comments: 2  
by kernel1983

grep for project search

本来是 --help 就可以看到的东西
grep 'xxx' .
在当前目录查找文件中的内容

grep 'xxx' . -r
在当前目录下的所有目录查找文件内容

grep 'xxx' . -r -n
输出结果加行号

grep 'xxx' . -r -n --include="*.py"
在当前目录下的所有目录中, 查找.py文件的内容

grep 'xxx' . -r -n --include="*.py" --exclude="__init__.py"
排除某些文件

已经够用了

传说中还有一个ack, perl写的, 输出结果比grep漂亮, 不过使用中缺少一些灵活的选项.
comments: 0  
by kernel1983

vim in multi files

一直以一个正常的程序员的名义, 拒绝vim, emacs这些古董. 其实是自己玩不转, 心里还是蠢蠢欲动的. 直到最近结识新同事, 意识到应该充分利用资源了.
TextMate是吃内存的. 考虑到回到上古董机器上工作的可能性, 所以还是挑一个好伺候的编辑器. 把内存留给更加需要的Firefox同志, 希望他也能学会省省. 理由之二.

以往对vim的认识只限于单文件编辑. 对于多文件, vim有window,buffer和tab三种处理. 我们一致认为用buffer实现文件之间的跳转最为方便.
另外, 全局文件搜索, 请参考grep.

:o .
:e .
打开目录选择文件, 这两条命令的区别不详, 可能是别名.

:bd
:bdelete
关闭buffer

:ls
:buffers
列出buffer

:bprev
:bp
:bnext
:bn
上一个/下一个buffer

最后, 推荐FuzzyFinder插件, 让你快速打开文件, 并在buffer之间跳转.
comments: 0  
by kernel1983

一键部署

对于快速原型项目, 一键部署能提升开发者的效率

Google App Engine的appcfg.py就是被开发人员喜爱的工具, 只需一条命令就可以将当前开发环境的代码玩玩整整的克隆到服务器上.

不过, 一条命令部署不等于一键部署, 我们要努力让开发人员更加简单的搞定一切.
我们如何来实现更加简单的部署?

拿django开发来说, 由于自带开发服务器, 我们在项目下建立两个命令
server.bat和upload.bat 使用.bat扩展名的原因是为了兼容window开发人员
对于linux开发人员, 启动开发服务器只需要打开终端进入项目目录输入
sh server.bat
在部署的时候输入
sh upload.bat

OK. 那么拿django来说, server.bat的内容就是
python manage.py runserver

而upload.bat的内容或许就是
scp -R . user@myhost.com:/home/user/proj


重要的是约定, 团队成员在拿到每一个项目的源代码的时候, 都可以快速的启动项目的测试服务器, 无论项目采用的是什么框架, 或者采用什么样的方式部署到哪台服务器, 都可以让开发人员有机会忽略一定的细节, 省略重复劳动, 高效完成任务.

除了GAE的专用的工具支持一条命令部署以外, 大部分开发人员还在与ftp客户端一同工作. 切换到编辑器, 修改代码保存; 切换到浏览器, 观察效果; 切换到终端查看debug信息; 切换到Filezilla, 上传代码. Filezilla的图形化操作, 往往不能被写入到命令行中, 我们可以使用其他的方法:

在某些大型项目中, 常常使用的部署流程, 比如: 修改代码, svn checkin, code review, 最后在终端中ssh到服务器后svn checkout来部署. 这种方式融合了版本管理和服务器部署, 而且可以即时删除无用的代码. 这种方法, 我们可以将ssh的命令行写在upload.bat中
ssh user@myhost.com 'cd ~/proj/;svn up'

相对而言, 较小的项目通过rsync, 比起svn方式来更加简洁, 一条命令就可以实现. rsync需要服务器的支持, 不过不像我们想象的那样, 需要服务器上打开独立的tcp端口. rsync只需要ssh支持就可以工作.
rsync -avz . user@myhost.com:/home/user/project/ --exclude "*.pyc" --exclude ".*" --delete

最后, 当服务器不能安装rsync, 我们只能使用scp来覆盖服务器上的一切文件了.
comments: 4  
by kernel1983

SMTP on Leopard

Leopard 上预装了 postfix, 但是smtp 服务 25 端口没有打开, 默认只能用 sendmail 发送邮件

PHP没有问题, 发送邮件可以用 sendmail 或者 smtp.
Python 倒是没有支持的那么完善, smtp 用到 smtplib, sendmail 命令则没有包装

解决方法有两种
自己写一个函数包装一下sendmail
def sendmail():
    sendmail_location = "/usr/sbin/sendmail" # sendmail location
    p = os.popen("%s -t" % sendmail_location, "w")
    p.write("From: %s\n" % "from@somewhere.com")
    p.write("To: %s\n" % "to@somewhereelse.com")
    p.write("Subject: thesubject\n")
    p.write("\n") # blank line separating headers from body
    p.write("body of the mail")
    status = p.close()
    if status != 0:
        print "Sendmail exit status", status

或者打开 smtp 端口
sudo postfix start
测试一下
telnet 127.0.0.1 25
不用的时候关闭
sudo postfix stop
comments: 0  
by kernel1983
1234567...29