0

PHP 関数mysql_connectは、4 番目のパラメーター '$new_link' TRUE を明示的に設定しない場合、既存の接続を返します。
Apache 環境で、$new_link を TRUE に設定せずにmysql_connectを呼び出すと、mysql 接続リソースの競合状態が発生する可能性がありますか?
CLI 環境では、競合状態が発生することを証明しました。しかし、Apacheではありません。なぜ?Apache は 1 つのプロセス モデルのみを使用しますか? 次のような CLI コードの例:

// create share memory
$nShmKey = ftok(__FILE__, 'i');
$nShmID = shm_attach($nShmKey, strlen($sArr) * 2);

// write the array to the shared memory
$nArrKey = 1;
shm_put_var($nShmID, $nArrKey, $arr);

// create semphore
$nSemID = sem_get(1, 1);

// child process consume the data in the shm
for($i = 0; $i < PROC_NUM; ++$i) {
    $nPID = pcntl_fork();

    if ($nPID == 0) {
        // child
        // create db link
        $oLink = mysql_connect(
                'my_server', 
                'my_user', 
                'my_password', 
                TRUE /*if set this false, it will cause race condition in each child*/
        );
        while (true) {
            sem_acquire($nSemID);

            // get the value
            $arrCur = shm_get_var($nShmID, $nArrKey);

            if (0 == count($arrCur) || $arrCur == FALSE) {
                // value out
                sem_release($nSemID);
                break;
            }
            $nVal = array_pop($arrCur);
            if (FALSE == shm_put_var($nShmID, $nArrKey, $arrCur)) {
                die('Failed to write array to shm');
            }
            sem_release($nSemID);

            // just insert the result to db
            mysql_query("INSERT INTO some_table(val) VALUES({$nVal})", $oLink);
        }
        exit(0);
    }
}

// wait for children
$n = 0;
while ($n < PROC_NUM) {
    $nStatus = -1;
    $nPID = pcntl_wait($nStatus, WNOHANG);
    if ($nPID > 0) {
        echo "{$nPID} exit\n";
        ++$n;
    }
}

// clear shm
sem_remove($nSemID);
shm_remove($nShmID);
echo "finished\n";
?>

mysql リンクがマルチプロセス間でうまく機能しないことはわかっています。私の質問は 、Apache で mysql リンクの競合状態が発生しないのはなぜですか?

4

1 に答える 1

2

いいえ、実行中のプロセス (同じスクリプト) 内で同じ接続のみを再利用します。また、PHP スクリプトは一般にマルチスレッド化されていないため、問題はありません。プロセスを fork する場合、同じ接続を共有していることに注意する必要がありますが、これは特殊なケースです。

接続がプロセス間で共有される接続プールの一種である永続的な接続を使用するオプションがあります。ただし、その場合でも、同じ接続が同時に 2 つのプロセスに分配されることはありません。一般に、MySql は接続が非常に高速であるため、永続的な接続を使用する価値はありません。

于 2012-08-02T08:08:56.663 に答える