HP进程之信号捕捉中的declare(ticks=1)

2019/11/13 16:38
阅读数 174

在使用PHP的PCNTL拓展时,发现在信号捕捉的例程中出现了declare(ticks=1)这条php语句,于是对其进行研究。

一. 语句在php中的意义
php中,declare(ticks=n)和register_tick_function(‘handel_function’)一般是配合使用的,其作用是在zend解释器每执行 N 条可计时的低级语句就会发生的事件,该事件发生后就可以处理已经注册的函数’handel_function’;

二. 在使用捕捉信号时使用该语句的思考
1.linux下应用编程中的signal机制(linux-signal机制资料来源博客《Linux 信号signal处理机制》)

这里写图片描述
每个进程都会采用一个进程控制块对其进行描述,进程控制块中设计了一个signal的位图信息,其中的每位与具体的signal相对应,这与中断机制是保持一致的。当系统中一个进程A通过signal系统调用向进程B发送signal时,设置进程B的对应signal位图,类似于触发了signal对应中断。发送signal只是“中断”触发的一个过程,具体执行会在两个阶段发生:

(1)、 system call返回。进程B由于调用了system call后,从内核返回用户态时需要检查他拥有的signal位图信息表,此时是一个执行点。

(2)、 中断返回。进程被系统中断打断之后,系统将CPU交给进程时,需要检查即将执行进程所拥有的signal位图信息表,此时也是一个执行点。

综上所述,signal的执行点可以理解成从内核态返回用户态时,在返回时,如果发现待执行进程存在被触发的signal,那么在离开内核态之后(也就是将CPU切换到用户模式),执行用户进程为该signal绑定的signal处理函数,从这一点上看,signal处理函数是在用户进程上下文中执行的。当执行完signal处理函数之后,再返回到用户进程被中断或者system call(软中断或者指令陷阱)打断的地方。

2.php使用singal为什么需要使用declare(ticks=n)语句
既然系统内核都提供了完整的signal的机制,第一想到的是,pcntl拓展要实现php的signal-api, 其直接将php方法与底层的singnal函数绑定就能实现了,不是吗?

(以下对于该问题的答案纯属个人思考)
答案是否定的,从上面linux中的signal机制可知道,其机制是针对c语言等强语言的,其对代码的中断造成对变量的影响是可控的。

但是对于PHP这样的脚本语言,一个语句底下可能是n句C语言执行,或者n+m句机器指令,如果在一条语句的执行过程中运行php的signal函数,那么很可能引起php的奔溃;

那么pcntl拓展怎么解决这个问题了,自然就会想到,如果信号来了先做标记,再等一句完整的php语句执行完了,然后再调用使用pcntl_signal注册的php回调函数,这样就保证了php环境的安全性。

而php中declare(ticks=n)和register_tick_function(‘handel_function’)就提供了这样的功能;

结论很清楚了,为了保证php环境的安全性和稳定性,pcntl拓展在实现signal上使用了“延后执行”的机制;因此使用该功能时,必须先使用语句declare(ticks=1),否则注册的singal-handel就不会执行了
 

 

 

 

declare 结构用来设定一段代码的执行指令。declare 的语法和其它流程控制结构相似:

declare (directive)
    statement

directive 部分允许设定 declare 代码段的行为。目前只有两个指令:ticks(更多信息见下面 ticks 指令)以及 encoding(更多信息见下面 encoding 指令)。

declare 代码段中的 statement 部分将被执行——怎样执行以及执行中有什么副作用出现取决于 directive 中设定的指令。

declare 结构也可用于全局范围,影响到其后的所有代码(但如果有 declare 结构的文件被其它文件包含,则对包含它的父文件不起作用)。

Tick(时钟周期)是一个在 declare 代码段中解释器每执行 N 条可计时的低级语句就会发生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 来指定的。

不是所有语句都可计时。通常条件表达式和参数表达式都不可计时。

在每个 tick 中出现的事件是由 register_tick_function() 来指定的。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部