developer's diary

最近はc#のエントリが多いです

PHPで非同期処理。(再起動にも負けないようにatコマンドを利用)

phpで非同期処理 - developer's diary
のやり方だとapacheを停止、または再起動するとkillされるようで途中で止まってしまいました。
なので、atを利用するやり方に修正。

#処理の流れ
ブラウザ
↓
index.php
↓
atコマンド
↓
worker.php

index.php

<?php
//プロセスが生きてるかチェック(生きてる:true,死んでる:false)
function checkRunProcess($pid_file){
        if(file_exists($pid_file)){
                $_pid = trim(file_get_contents($pid_file));
                system("kill -s 0 {$_pid}", $_status);
                if($_status){
                        unlink($pid_file);
                        return false;
                }else{
                        return true;
                }
        }
}

if(checkRunProcess("worker.pid")){
        echo "処理が終わっていません。";
}else{
        shell_exec('echo "/usr/bin/php worker.php > /dev/null 2>&2 " | at now > /dev/null 2>&2 &');
        echo "非同期処理を実行しました。";
}


worker.php

<?php
//HTTP経由での起動時は処理を行わない
if($_SERVER['DOCUMENT_ROOT']){
exit(0);
}

$pid_file = "worker.pid";
if(checkRunProcess($pid_file)){
        echo "処理が終わっていません。";
        exit(0);
}else{
        system('echo '.getmypid().' > '.$pid_file, $_status);
        if($_status){
                die('ERROR: PIDファイルの作成に失敗しました。');
        }

        //主処理
        main();
        unlink($pid_file);
}

//プロセスが生きてるかチェック(生きてる:true,死んでる:false)
function checkRunProcess($pid_file){
        if(file_exists($pid_file)){
                $_pid = trim(file_get_contents($pid_file));
                system("kill -s 0 {$_pid}", $_status);
                if($_status){
                        unlink($pid_file);
                        return false;
                }else{
                        return true;
                }
        }
}

//主処理
function main(){
        foreach (range(0, 10) as $number) {
                $fp = fopen('test.txt','w');
                fwrite($fp,$number."\n");
                fclose($fp);
                sleep(10);
        }
}

ブラウザから実行を行い、httpdを再起動しても問題なくkillされずに処理が行われていました。