0

長時間 (6 時間以上) 実行されていたスクリプトがいくつかありました。それらはすべて、それを実行するメインループと、mysql クエリをトリガーしてプロセスを「完了」として通知する登録済みのシャットダウン関数を含んでいました。

スクリプト全体をより速く完了するために、これらのメイン ループ内で pcntl_fork() を使用して、各ラウンドを異なるプロセスとして実行することにしました。

問題なく動作しますが、各子プロセスはまだシャットダウン機能に登録されています。したがって、子プロセスが完了するたびに、その mysql クエリが呼び出され、スクリプトが完了したことが通知されます。子プロセスのシャットダウン機能を無効にするにはどうすればよいですか?

何が起こっているのかを理解するためのサンプルコード:

  • common.php

    register_shutdown_function('shutdown');
    function shutdown()
    {   global $objDb,$arg_id ;
    
           echo "\n\n Executing queue process shutdown function.";
           $objDb->query("UPDATE queue_args SET done='1' WHERE id='{$arg_id}'"); 
    }
    
  • loop.php

    include('common.php');
    for ($i=1;$i<=200;$i++){    
           $pid = pcntl_fork(); 
           if (!$pid) {
               //child proccess - do something without calling the shutdown function
               posix_kill(getmypid(),9);
           } 
    }  exit(); //this is when the shutdown function should eventually be called
    

ありがとう

4

2 に答える 2

2

次のように、if内にシャットダウン関数を登録できます。

if ($pid) {
    if(!$registered) {
        $registered = true;
        register_shutdown_function('shutdown');
    }
}else{
    //child proccess - do something without calling the shutdown function
    posix_kill(getmypid(),9);
} 
于 2012-08-15T08:53:21.680 に答える
0

できません。

フォークした後、子プロセスにフラグを設定し、シャットダウン関数でポーリングすることができます。設定されている場合は、早期に戻ります。または、フォークする前に親pidを保存し、shutdown関数内で、現在のpidでない場合は早期に戻ります。または、fork後に親プロセスに関数を登録します。

if(!$ pid){posix_kill(getmypid()、9); }

これは、シャットダウン関数が子プロセスで呼び出されないようにするための非常に悪い方法ですが、他のあらゆる種類の影響があります。PHPは正常にシャットダウンせず、バッファーはフラッシュされません。たぶんあなたはこれをする必要があります:

#!/usr/bin/php
<?php

$arg_id = exec('task_which_forks.php');
exec("queue_clean_up.php $arg_id");
于 2012-08-15T08:54:28.333 に答える