-1

本当に多くの努力を重ねた結果、php Zend アプリケーションをマルチスレッドで実行することができました。そのために、php pcntl_* 関数を使用するために、Apache を CGI モードで構成しました。私はこの問題を抱えていますこれは私のフォークです

    function fork() {
    $pid = pcntl_fork();
    if ($pid == -1)
        throw new Exception('fork error on Task object');
    elseif ($pid) {
        # we are in parent class
        $this->pid = $pid;
        # echo "< in parent with pid {$his->pid}\n";
    } else {
        # we are in child
        $sid = posix_setsid();
        if ($sid < 0) {
            exit;
        }
        $this->run();
    }
}

この関数を呼び出すたびに、プロセスが作成され、問題なく実行されますが、ブラウザーで Web ページを制御できなくなりました (Web サイトをナビゲートできなくなりました)。エラーが発生するまで、ページを長時間ロードしているようです。ブラウザをシャットダウンして(再接続できない新しいタブだけで)、サーバーに再接続する必要があります。最後に作成されたプロセスが http ポートでリッスンしている可能性がありますか? どうすればこれを解決できますか? ありがとう

4

1 に答える 1

0

私にはセッションロックの問題のように聞こえます-呼び出すたびにsession_start()、PHPはディスク上のセッションファイルを排他的にロックするため、2つのPHPページが同じセッションに競合する情報を書き込むことはできません。そのロックが設定されている間に呼び出すとsession_start()、セッションのロックが終了するまで(またはまたはを呼び出すまで)「ハング」しsession_write_close()ますsession_destroy()

私の推測では、PHPプロセスを「フォーク」する前に、セッションを開いており(または、他の排他ロックを取得している可能性があります)、PHPはマルチスレッドで使用するように設計されていないため、このロックは適切に解放されていません。 (または、むしろ、マルチプロセス)環境。

system真のフォークをPHPで動作させるよりも、またはを使用してまったく新しいPHPスクリプトを生成しexec、などのメッセージングフレームワークを使用してシリアル化されたデータを渡す方がよいでしょうZeroMQ。これにより、親に基づいて子の初期条件を設定できるだけでなく、実際に子から情報を返すことができます。

ただし、この方法で作成された子プロセスは「コマンドラインSAPI」の下で実行されることを忘れないでください。これは別の対象となる可能性があり、php.ini通常は当たり前のように定義されていないものです。$_SERVER['DOCUMENT_ROOT']

于 2012-08-24T13:22:36.877 に答える