Linux Install Memo

サーバー管理者によるLinux関連ソフトのインストールメモ

Home » □libeventは便利だな(PHP)

□libeventは便利だな(PHP)

以前は通信系をこねくり回していたこともあって、割り込み処理の面倒
くささとありがたさの両方を知っている。で、今作っているシステムで
やっぱり割り込み処理を使いたくなったのだけど、ベースがPHPなので
さてどうしたものか?っていうか、そもそもあるの?

割り込みの理屈というかポイントは、

・グローバルかつ静的な領域(ふらふらとアドレスが移動しない)変数を
 用意する
・通常処理では、上記の変数が変化しない限り待ち状態とかにする。
・割り込み処理では、割り込みが来たら出来るだけ短時間で必要な処理
 をして、必要に応じて通常処理に上記変数を使って結果を渡して処理
 を終わる。

こんなところかな。

よくこういう処理は、どこかとのソケット通信や外部呼出しプロセスの
処理結果待ちなんてに使うんだけどね。

で、asmとかCだとべたべたバリバリにこの辺は書けるのでらくちんなの
だけど、よりユーザーフレンドリな言語、っていうかPHPとかではこんな
処理をどう書いたらいいのか「?」なわけですわ。select()で割り込み
処理関数のポインタを渡すとか、面倒というかそもそも出来るのか?と
いうわけ。

で、どうしたもんかなとうろうろしていたら、PHPのプロセス制御に最初
はexpectというのがあったけど、それよりもlibveventというPECLで便利
なライブラリがありましたとさ。

割り込み処理を下等(笑)言語で作ったことがある人なら

http://jp.php.net/manual/ja/libevent.examples.php

ここにサンプルがあるので、それを参照すれば超簡単。

実際のPHPの書き方をメモっとくことにする。

例:

??????? :
??????? :
??????? :
// 外部呼び出し処理結果の変数宣言(0:OK, 1以上:エラー, -1:処理待ち)
static $PROCRESULT = -1; // 最初は処理待ちにしとく
??????? :
??????? :
??????? :
// ——————–
// event_int:libeventを使ったタイムアウト処理
// ——————–
// libeventを使ったタイムアウト処理
function event_int($buf, $arg)
{
??? //? 外部呼び出し処理結果の変数宣言(0:OK, 1以上:エラー, -1:処理待ち)
??? global $PROCRESULT;

??? print “EVENT INT!\n”;

??? // 割り込みを起こしたバッファからデータ取得
??? $data = event_buffer_read($buf, 4096);

??? print “EVENT READ!\n”;
??? print $data;

??? // 結果判定
??? if (preg_match(‘/ OK:(.*) /’, $data, $result))
??? {
??????? // 処理のステータスをそのまま設定(0か1以上が返ると想定※)
??????? $PROCRESULT = $result[1];
??????? print “PROC END!\n”;
??????? // ループを抜ける
??????? event_base_loopexit($arg);
??? }
??? print “EVENT END!\n”;
}

function event_err($buf, $what, $arg)
{
??? print “エラー処理を書くんだけど、いらなきゃ空のままで…\n”;
}
??????? :
??????? :
??????? :
// ————————————————————
// Main
// ————————————————————
??????? :
??????? :
??????? :
??????? // libeventを使ったタイムアウト処理
??????? $PROCRESULT = -1; // 処理待ち
??????? $EVENT_BASE = event_base_new();
??????? $EVENT_BUFFER = event_buffer_new($FP, “event_int”, NULL, “event_err”, $EVENT_BASE);
??????? event_buffer_timeout_set($EVENT_BUFFER, 10, 10); // とりあえず10秒タイマ
??????? event_buffer_base_set($EVENT_BUFFER, $EVENT_BASE);
??????? event_buffer_enable($EVENT_BUFFER, EV_READ);
???????
??????? // 外部呼び出し処理の結果待ち
??????? $result = event_base_loop($EVENT_BASE);
???????
??????? if ($PROCRESULT == -1) // 処理待ちなのになぁ…
??????? {
??????????? if ($result == 1) // タイムアウト
??????????? {
??????????????? $RESULT_STR = “Timeout”;
??????????? }
??????????? elseif ($result == -1) // libeventがなんかのエラー
??????????? {
??????????????? $RESULT_STR = “libevent Error”;
??????????? }
??????????? else? // 想定外のようわからんエラー
??????????? {
??????????????? $RESULT_STR = “ERR1 PROCRESULT = $PROCRESULT result = $result”;
??????????? }
??????? }
??????? elseif ($PROCRESULT > 0) // 処理はエラーで終了
??????? {
??????????? $RESULT_STR = “PROC NG”;
??????? }
??????? elseif ($PROCRESULT == 0) // 処理は正常に終了
??????? {
??????????? $RESULT_STR = “PROC OK”;
??????? }
??????? else // ほんまにようわからんエラー発生ってことで
??????? {
??????????? $RESULT_STR = “ERR2 PSRESULT = $PSRESULT, result = $result”;
??????? }
??????? :
??????? :
??????? :

こんな感じて、selectなんたらがどうたらこうたらと書くよりもらくらく
に割り込み処理(正確にはタイマー処理か)ができましたとさ。

Name of author

Name: admin

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です