Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
signal の話
或いは
Zend Signals とは何か
2016/12/11
第七回闇PHP勉強会
do_aki
updated 2016-12-13
@do_aki
@do_aki
http://do-aki.net/
signal とは
• UNIX系OS に古くからあるプロセス間通信の
一つ
• プロセスがシグナル(実態は整数) を受信す
ると、あらかじめ設定した処理(シグナルハ
ンドラ)が実行される(乱暴に言えば割り込
みが発生する)
• シグナルハンド...
php においては
• pcntl 拡張を利用することで signal 処
理を管理することが可能
• pcntl_signal(signo, callback)
pcntl_signal の利用例<?php
declare(ticks=1);
$signal_callback_function = function ($signo) {
echo "receive signal: {$signo}¥n"...
pcntl による signal 処理
これは単純に
“シグナルを受信したら
callback が実行される”
というものではない
pcntl_signal が行うこと
• signal_table に シグナル番号とコール
バック関数を登録
• 該当シグナル番号に対するシグナルハン
ドラとして pcntl_signal_handler を
(実行環境に対して) 登録
• ...
signal handling
pcntl_signal_handler
signo
pcntl_signal_dispatch
SIGHUP funcA
SIGINT funcB
SIGALRM funcC
……
signal table
l...
シグナルハンドラの制約
• どんなタイミングであっても呼ばれる可能性
がある
– 当然 php のスタックフレームは無視
• 呼び出し可能なシステムコールが限られる
– man signal 7 を参照
最小限の処理(受信したことの記録) だけ...
tick による dispatch
• declare(ticks = N); // (N >= 1)
– N個の tick 可能命令ごとに ZEND_TICKS opcode
が発行される
– 詳しくは以前書いた記事を参照
http://d....
vm_interrupt による dispatch
• pcntl_async_signals(true); // 7.1~
– declare(ticks=1) が不要になる
– pcntl_signal_handler が
EG(vm_in...
dispatch by vm_interrupt
pcntl_signal_handler
pcntl_signal_dispatch
[receive signal]
EG(vm_in
terrupt)
PHP VM
zend_interru...
EG(vm_interrupt)
• 元は Safe timeout handling により導入
された仕組み
• EG(vm_interrupt) かつ EG(timed_out)
ならば (zend_interrupt_function ...
max_execution_time の実装
• setitimer (ITIMER_PROF)を利用 (!WIN32)
– プログラムの実行時間が指定時間経過すると
SIGPROF が飛ぶ
– php に kill –PROF すると終了する...
Safe timeout handling
zend_timeout_
handler
PHP VM
zend_timeout
set1
zend_timeout
~7.0 (or !ZEND_SIGNALS)
7.1~ (with ZEND_...
ZEND_SIGNALS
• ZendEngineやSAPI,拡張 と 実行環境 の間に作ら
れた signal 処理の中間層
– 環境依存な signal 処理を画一的に扱うための仕組み
– 7.1 から デフォルトで有効
• php スクリ...
Deferred Signals
• ZEND_SIGNAL_BLOCK_INTERRUPTIONS (=
HANDLE_BLOCK_INTERRUPTIONS) により、
シグナルハンドラの実行を延期することが可
能
– 現状使ってるのは o...
ZEND SIGNALS
zend_signal_handler_defer
1 handler1
2 hanlder2
3 hanlder3
……
SIGG(handlers)
zend signal queue
signo
signal b...
まとめ
– pcntl signal
– EG(vm_interrupt)
– Safe timeout handling
– ZEND_SIGNALS
• について話しました
• 7.1 で php における signal 処理はだいぶ大き
...
参照
• Zend Signal Handling
– https://wiki.php.net/rfc/zendsignals
– https://github.com/php/php-
src/commit/939875133a2c389d...
Upcoming SlideShare
Loading in …5
×

signal の話 或いは Zend Signals とは何か

4,542 views

Published on

第七回闇PHP勉強会

Published in: Technology
  • Be the first to comment

signal の話 或いは Zend Signals とは何か

  1. 1. signal の話 或いは Zend Signals とは何か 2016/12/11 第七回闇PHP勉強会 do_aki updated 2016-12-13
  2. 2. @do_aki @do_aki http://do-aki.net/
  3. 3. signal とは • UNIX系OS に古くからあるプロセス間通信の 一つ • プロセスがシグナル(実態は整数) を受信す ると、あらかじめ設定した処理(シグナルハ ンドラ)が実行される(乱暴に言えば割り込 みが発生する) • シグナルハンドラが設定されてないシグナル は、無視されるかあるいは既定の動きをする (その多くはプログラムの終了)
  4. 4. php においては • pcntl 拡張を利用することで signal 処 理を管理することが可能 • pcntl_signal(signo, callback)
  5. 5. pcntl_signal の利用例<?php declare(ticks=1); $signal_callback_function = function ($signo) { echo "receive signal: {$signo}¥n"; exit; }; pcntl_signal(SIGINT, $signal_callback_function); while(1) { sleep(1); } // 通常の動きだけでは永久ループ // Ctrl + C 押下で、 "receive signal: 2" を出力して終了
  6. 6. pcntl による signal 処理 これは単純に “シグナルを受信したら callback が実行される” というものではない
  7. 7. pcntl_signal が行うこと • signal_table に シグナル番号とコール バック関数を登録 • 該当シグナル番号に対するシグナルハン ドラとして pcntl_signal_handler を (実行環境に対して) 登録 • 実際にコールバック関数を呼ぶのは pcntl_signal_dispatch
  8. 8. signal handling pcntl_signal_handler signo pcntl_signal_dispatch SIGHUP funcA SIGINT funcB SIGALRM funcC …… signal table lookup & call signo pending signal queue [receive signal] [tick or vm_interrupt]
  9. 9. シグナルハンドラの制約 • どんなタイミングであっても呼ばれる可能性 がある – 当然 php のスタックフレームは無視 • 呼び出し可能なシステムコールが限られる – man signal 7 を参照 最小限の処理(受信したことの記録) だけ 行い、あとから適切なタイミングでコール バックを実行(dispatch)している なので
  10. 10. tick による dispatch • declare(ticks = N); // (N >= 1) – N個の tick 可能命令ごとに ZEND_TICKS opcode が発行される – 詳しくは以前書いた記事を参照 http://d.hatena.ne.jp/do_aki/20151204/14491 97226 • ticks=1 ならば、だいたい php スクリプト1行 ごとに発行されてる – 1行ごとに pcntl_signal_dispatch が呼ばれるイ メージ • ファイル単位で、コンパイル時に影響 – ticks 指定忘れるとシグナルコールバックされない
  11. 11. vm_interrupt による dispatch • pcntl_async_signals(true); // 7.1~ – declare(ticks=1) が不要になる – pcntl_signal_handler が EG(vm_interrupt) = 1 するようになる • EG(vm_interrupt) が 1 の場合、 PHP VM は、 zend_interrupt_function (関数ポインタ) を呼ぶ – Opcode ひとつ処理するたびにチェックしている – pcntl の MINIT で zend_interrupt_function = pcntl_interrupt_function してて、このなかで pcntl_signal_dispatch を呼ぶ – ZEND_TICKS Opcode で毎回呼ばれるよりも低コスト – (async_signals しなくても pcntl 以外が vm_interrupt をセットすれば dispatch される気がする)
  12. 12. dispatch by vm_interrupt pcntl_signal_handler pcntl_signal_dispatch [receive signal] EG(vm_in terrupt) PHP VM zend_interrupt_function = pcntl_interrupt_function [each opcode] set1
  13. 13. EG(vm_interrupt) • 元は Safe timeout handling により導入 された仕組み • EG(vm_interrupt) かつ EG(timed_out) ならば (zend_interrupt_function ではなく) zend_timeout(0) を呼ぶ(おそらくこちらが本命) • EG(timed_out) は php スクリプトの実行 時間が max_execution_time を超えたとき に設定される
  14. 14. max_execution_time の実装 • setitimer (ITIMER_PROF)を利用 (!WIN32) – プログラムの実行時間が指定時間経過すると SIGPROF が飛ぶ – php に kill –PROF すると終了する • zend engine でシグナルハンドラ を設定し てる – 7.0まで: signalシステムコールを利用 (直接 zend_timeout が呼ばれてた) – 7.1から: zend_signalを利用 (ZEND_SIGNALS) (zend_timeout_handler) この中で EG(timed_out) = 1
  15. 15. Safe timeout handling zend_timeout_ handler PHP VM zend_timeout set1 zend_timeout ~7.0 (or !ZEND_SIGNALS) 7.1~ (with ZEND_SIGNALS) EG(vm_in terrupt) EG(timed _out)
  16. 16. ZEND_SIGNALS • ZendEngineやSAPI,拡張 と 実行環境 の間に作ら れた signal 処理の中間層 – 環境依存な signal 処理を画一的に扱うための仕組み – 7.1 から デフォルトで有効 • php スクリプトにおける pcntl のようなものを、 C言語で(コアや拡張向けに) 提供した感じ – zend_signal によって実行環境に登録されるシグナル ハンドラは zend_signal_handler_defer に統一さ れる (シグナルハンドラとして指定した関数はここか ら間接的に呼ばれる)
  17. 17. Deferred Signals • ZEND_SIGNAL_BLOCK_INTERRUPTIONS (= HANDLE_BLOCK_INTERRUPTIONS) により、 シグナルハンドラの実行を延期することが可 能 – 現状使ってるのは opcache のみ – 解放は ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS – シグナルハンドラの実行タイミングを制御するこ とで、共有メモリ操作時の不安定な動きを解消し ている(らしい) – 以前はメモリ操作周りでも利用されていたが、 7.0 でのメモリマネージャ刷新によって不要に なった?
  18. 18. ZEND SIGNALS zend_signal_handler_defer 1 handler1 2 hanlder2 3 hanlder3 …… SIGG(handlers) zend signal queue signo signal blocked (HANDLE_BLOCK_INTERRUPTIONS) signal unblocked HANDLE_UNBLOCK_INTERRUPTIONS signo callzend_signal_handler
  19. 19. まとめ – pcntl signal – EG(vm_interrupt) – Safe timeout handling – ZEND_SIGNALS • について話しました • 7.1 で php における signal 処理はだいぶ大き く変容します – おそらく ふつーに php スクリプト書いている人に は気づかれないような変化。 けど、これにより安定化とパフォーマンス向上が図 られているのです
  20. 20. 参照 • Zend Signal Handling – https://wiki.php.net/rfc/zendsignals – https://github.com/php/php- src/commit/939875133a2c389d621a9999a8ede3ddbc9b6637 • Asynchronous Signal Handling (without TICKs) – https://wiki.php.net/rfc/async_signals – https://github.com/php/php- src/commit/c03ccfe78d6b13cab9546efb616a42a8f3e8a4e0 • Safe execution timeout handling – https://www.mail-archive.com/internals@lists.php.net/msg76907.html – https://github.com/php/php-src/pull/1876 • Enable Zend Signals by Default – https://www.mail-archive.com/internals@lists.php.net/msg86428.html

×