Press "Enter" to skip to content

Zend Signal in PHP 5.4

在PHP5.4中, 根据由Rasmus提交的RFC, 引入了一套新的信号处理机制, 目的是为了使得信号屏蔽机制可以应用到任何SAPI中, 并且提高在这个过程中的PHP性能.
新的机制, 叫做zend signal, 它的理念, 来自Yahoo的"延迟信号处理"(Yahoo signal deferring mechanism), 而后, facebook把这套理念加入了PHP中, 为了提升PHP+Apache 1.X下PHP调用ap_block/ap_unblock的性能.
在详细介绍之前, 我想还是先介绍下引入这个新机制的背景:
之前我写过俩篇blog, 介绍过因为超时信号导致PHP crash的案例:深入理解PHP内存管理之一个低概率Core的分析一个低概率的PHP Core dump , 在其中, 我说过, 其实PHP在关键操作的时候, 是预留了信号屏蔽机制的:HANDLE_BLOCK和UNBLOCK_INTERRUPTIONS. 但是, 这俩个宏只是Hook, 需要SAPI自己去实现, 目前来说, 也只有Apache 1.x的SAPI实现了这俩个宏, 也就是使用ap_block和ap_unblock.
而对于"一个低概率的PHP Core dump "中所描述的情况, 如果我们为了解决它, 而在每次有错误发生的时刻, 都引入一对屏蔽/取消屏蔽的系统调用, 那么这个性能损失将会很明显, 所以一直没有很好的解决这个问题.
那么zend signal的做法是:
1. 在zend engine启动时刻, 会为下面的信号注册信号处理函数: SIGALRM, SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2, SIGPROF(*nix下), 如果这些信号已经有了处理函数, 那么会把旧的处理函数保存下来.
2. 当有信号发生时候, zend_signal_handler_defer会首先判断, 当前是否处于block区域, 如果不是, 则信号对应的旧的处理函数将会被调用. 如果是, 那么信号处理函数不会被立即调用, 而是一直等到HANDLE_UNBLOCK_INTERRUPTIONS以后, 退出block区域, 才调用信号处理函数. 如果有多个信号发生, 则信号将会排队等候.
3. zend signal使用zend_signal_globals_t.depth计数, 来判断是否处于block区域, HANDLE_BLOCK递增, HANDLE_UNBLOCK_INTERRUPTIONS递减.当 zend_signal_globals_t.depth大于0, 则表示在block中, 否则就表示不在. 这样就保证了性能(避免以前调用sigaction来屏蔽信号).
另外, zend signal为PHP提供了新的信号处理注册接口: zend_signal.
更加详细的信息, 可以参看[RFC]Zend Singal
在zend signal引入的大背景下, 我终于解决了文章开头所说的超时信号可能导致crash的问题:#60038. (only in 5.4)
不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.
谢谢
更多更新信息, 请关注:Changelog

9 Comments

  1. geometry dash
    geometry dash December 28, 2020

    No Database Connections, No complex logic.

  2. Newer
    Newer October 27, 2011

    哈哈,5.4中修复了好多博主提供的BUG啊

  3. liexusong
    liexusong October 23, 2011

    鸟哥的意思是说PHP5.4支持信号,PHP支持信号靠谱吗?

  4. 小白
    小白 October 21, 2011

    @.@能否举个列子?

  5. dongdong
    dongdong October 20, 2011

    可否移驾看下我一个php问题,挺难的,一堆人吵了半天了。
    我想用php做个“互相关联的tag”系统。
    就是各个tag之间互相关联,整体形成一个图结构。
    我的办法是一个mysql表建3个字段,
    id,tag内容,tag和其他tag的关联。
    数据库存储数据后,生成array结构的tag内容为缓存,前台直接读取,防止tag多了遍历过大数据库承受不住。
    现在问题是这个存储tag关系的array结构,我想构建个图结构的数组,网址中我搞了两个,但不知是否能行,博主是中国第一php牛人,可否看下?
    http://bbs.phpchina.com/thread-225148-1-1.html
    php两种array结构用来逻辑模拟图,那种更好效率更高

  6. 林中的熊宝宝
    林中的熊宝宝 October 19, 2011

    虽然不明白,不过好厉害啊

Comments are closed.