终于到了组装成型的时刻了,通过 telnet 玩了几把 echodemo ,看到一行一行的回显,不禁心情大好。 ?php class echodemo { public static function init($server, $conf) { log_debug($server, init in php.\n); return true; } public static function inpu
终于到了组装成型的时刻了,通过telnet玩了几把echodemo,看到一行一行的回显,不禁心情大好。
这里最值得赞叹的就是process函数对于sendrecv扩展调用,这里背后通过协程其实已经实现了一次异步网络交互:既能像同步cgi般书写逻辑代码,又能无痛地享受异步的高并发。
愿望是美好的,现实是残酷的!
我这时突然心血来潮:来压测一把性能吧,看看相比于原生c++代码有多大的性能衰减。单次请求1kb,施以1w/s的压力,压了一会coredump了。
内存泄漏?协程栈溢出?...
期间各种折腾:gdb,修改协程栈大小,google,咨询phper ...
很快到了晚上,该查的都查过了,该问的都问过了,实在没辙了,停下来喝杯茶:“call_user_function可重入么”?想到这一层,相信了解协程本质的兄弟又秒懂了:你妹的,人家实现zend的时候怎么知道调用线程还会玩协程进行用户态调度啊,这个黑盒里面一切皆有可能啊!全局变量、静态变量 ...
好吧,去掉sendrecv这类基于协程的扩展,重新压测,单worker对于3w/s的echo还是轻松无压力的。
结局
虽然这次最吸引人的一个feature最终未能实现,不过我还是很开心,因为再次印证了一个观点:思考往往比蛮干高效百倍,尤其在处理棘手问题时,无头苍蝇般乱闯乱撞往往费力不讨好,此时,如果能够冷静下来,尽力搜集现有知识储备,说不定灵感就来光顾你了。
未来可能的方向:php从5.5版本引入了yield,感觉如果挖掘出来zend对于yield的支持细节,说不定有希望和我们的c框架很好的融合,但是总觉得是个填不平的大坑。如果抛开其它因素,也许我还是希望选择golang一类语言直接享受goroutine的优势吧,哈哈!
附录php扩展开发及内核应用
http://www.walu.cc/phpbook/preface.md
编译php扩展的两种方式
http://521-wf.com/archives/227.html
如何使用c++开发php扩展(上)
http://521-wf.com/archives/241.html
如何使用c++开发php扩展(下)
http://521-wf.com/archives/245.html
wrapping c++ classes in a php extension
http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/