Heim  >  Artikel  >  php教程  >  一次失败的PHP扩展开发之旅

一次失败的PHP扩展开发之旅

WBOY
WBOYOriginal
2016-06-06 20:01:41850Durchsuche

终于到了组装成型的时刻了,通过 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,看到一行一行的回显,不禁心情大好。

<?php class EchoDemo {
        public static function init($server, $conf) {
            log_debug($server, "init in php.\n");
            return true;
        }   

        public static function input($server, $req, $ext_info = array()) {
            log_debug($server, "input in php.\n");
            return strlen($req);
        }   

        public static function route($server, $req, $ext_info = array()) {
            log_debug($server, "route in php.\n");
            return 1;
        }   

        public static function process($server, $req, $ext_info = array()) {
            log_debug($server, "process in php.\n");
            $ret = sendrecv($req, strlen($req), $rsp, 65535, "127.0.0.1", 2345, 500);
            if ($ret != 0) {
                log_debug($server, "sendrecv fail. ret=$ret");
                return false;
            }   
            log_debug($server, "sendrecv finish. rsp=$rsp");
            return true;
        }   

        public static function fini($server) {
            log_debug($server, "fini in php.\n");
        }   
    }
?>

这里最值得赞叹的就是process函数对于sendrecv扩展调用,这里背后通过协程其实已经实现了一次异步网络交互:既能像同步CGI般书写逻辑代码,又能无痛地享受异步的高并发。

愿望是美好的,现实是残酷的!

我这时突然心血来潮:来压测一把性能吧,看看相比于原生C++代码有多大的性能衰减。单次请求1KB,施以1w/s的压力,压了一会coredump了。

内存泄漏?协程栈溢出?...

期间各种折腾:GDB,修改协程栈大小,Google,咨询PHPer ...

很快到了晚上,该查的都查过了,该问的都问过了,实在没辙了,停下来喝杯茶:“call_user_function可重入么”?想到这一层,相信了解协程本质的兄弟又秒懂了:你妹的,人家实现Zend的时候怎么知道调用线程还会玩协程进行用户态调度啊,这个黑盒里面一切皆有可能啊!全局变量、静态变量 ...

好吧,去掉sendrecv这类基于协程的扩展,重新压测,单worker对于3w/secho还是轻松无压力的。

结局

虽然这次最吸引人的一个Feature最终未能实现,不过我还是很开心,因为再次印证了一个观点:思考往往比蛮干高效百倍,尤其在处理棘手问题时,无头苍蝇般乱闯乱撞往往费力不讨好,此时,如果能够冷静下来,尽力搜集现有知识储备,说不定灵感就来光顾你了。

未来可能的方向:PHP5.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/

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn