0

如果没有明确设置第四个参数 '$new_link' TRUE,则PHP 函数mysql_connect返回一个现有连接。
在apache环境下,不设置$new_link TRUE就调用mysql_connect是否会导致mysql连接资源竞速?
在 CLI 环境中,我已经证明确实出现了竞态条件。但不是在阿帕奇。所以为什么?apache是​​否只使用一种进程模型?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 进程,你应该知道你正在共享相同的连接,但这是一种特殊情况。

有一个使用持久连接的选项,它是一种连接池,连接在进程间共享。但即便如此,相同的连接也不会同时发送到两个进程。一般来说,使用持久连接并不值得,因为 MySql 的连接速度非常快。

于 2012-08-02T08:08:56.663 回答