HP進程之信號捕捉中的declare(ticks=1)

在使用PHP的PCNTL拓展時,發如今信號捕捉的例程中出現了declare(ticks=1)這條php語句,因而對其進行研究。php

一. 語句在php中的意義
php中,declare(ticks=n)和register_tick_function(‘handel_function’)通常是配合使用的,其做用是在zend解釋器每執行 N 條可計時的低級語句就會發生的事件,該事件發生後就能夠處理已經註冊的函數’handel_function’;linux

二. 在使用捕捉信號時使用該語句的思考
1.linux下應用編程中的signal機制(linux-signal機制資料來源博客《Linux 信號signal處理機制》)編程

這裏寫圖片描述
每一個進程都會採用一個進程控制塊對其進行描述,進程控制塊中設計了一個signal的位圖信息,其中的每位與具體的signal相對應,這與中斷機制是保持一致的。當系統中一個進程A經過signal系統調用向進程B發送signal時,設置進程B的對應signal位圖,相似於觸發了signal對應中斷。發送signal只是「中斷」觸發的一個過程,具體執行會在兩個階段發生:api

(1)、 system call返回。進程B因爲調用了system call後,從內核返回用戶態時須要檢查他擁有的signal位圖信息表,此時是一個執行點。安全

(2)、 中斷返回。進程被系統中斷打斷以後,系統將CPU交給進程時,須要檢查即將執行進程所擁有的signal位圖信息表,此時也是一個執行點。函數

綜上所述,signal的執行點能夠理解成從內核態返回用戶態時,在返回時,若是發現待執行進程存在被觸發的signal,那麼在離開內核態以後(也就是將CPU切換到用戶模式),執行用戶進程爲該signal綁定的signal處理函數,從這一點上看,signal處理函數是在用戶進程上下文中執行的。當執行完signal處理函數以後,再返回到用戶進程被中斷或者system call(軟中斷或者指令陷阱)打斷的地方。.net

2.php使用singal爲何須要使用declare(ticks=n)語句
既然系統內核都提供了完整的signal的機制,第一想到的是,pcntl拓展要實現php的signal-api, 其直接將php方法與底層的singnal函數綁定就能實現了,不是嗎?設計

(如下對於該問題的答案純屬我的思考)
答案是否認的,從上面linux中的signal機制可知道,其機制是針對c語言等強語言的,其對代碼的中斷形成對變量的影響是可控的。code

可是對於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() 來指定的。

相關文章
相關標籤/搜索