Взаимное исключение PHP (взаимное исключение)

Прочитайте некоторые тексты о привязке PHP.
Они все, главным образом, прямо к http://php.net/manual/en/function.flock.php.

Эта страница говорит об открытии файла на жестком диске!!

Это действительно так? Я имею в виду, это делает блокировку действительно дорогой - это означает каждый раз, когда я хочу заблокировать, я должен буду получить доступ к жесткому диску), =

Может больше успокаивать меня восхитительными новостями?

Править:

Из-за некоторых ответов я имею здесь, я хочу спросить это;
Мой сценарий будет работать только одним потоком или несколькими? Поскольку, если это одним затем, мне, очевидно, не нужно взаимное исключение. Существует ли краткий ответ?

Что точно я пытаюсь сделать

Спрошенный ircmaxell.
Это - история:

У меня есть два FTP-сервера. Я хочу смочь показать в моем веб-сайте, сколько подключенных пользователей онлайн.
Так, я думал, что эти FTP-серверы будут "POST" их статистика к определенной странице Сценария PHP. Давайте предположим, что URL этой страницы является "http://mydomain.com/update.php".

На основной странице веб-сайта ("http://mydomain.com/index.php") я отображу кумулятивную статистику (подключенные пользователи).

Именно.

Моя проблема состоит в том, что я не уверен, будет ли, когда один FTP-сервер обновляет его статистику, в то время как другой делает это также, информация смешана.
Как когда многопоточность; Два потока увеличивают некоторую "международную" переменную одновременно. Этого не произойдет как ожидалось, если Вы не будете синхронизировать между ними.
Так, у меня будет проблема? Да, нет, возможно?

Возможное решение

Думая трудно обо всем этом день долго, у меня есть идея здесь, и я хочу, чтобы Вы дали свое мнение.
Как сказано эти FTP-серверы отправят свою статистику, один раз в 60 секунд.
Я думаю о наличии этого файла "stats.php".
Это будет включено в сценарий обновления, что FTP-серверы переходят к ("update.php") и на уровне "index.php" страницы, где посетители видят, сколько пользователей онлайн.
Теперь, когда FTP-сервер обновляет, сценарий в "update.php" изменит "stats.php" с новой кумулятивной статистикой.
Сначала это прочитает статистику, включенную в "stats.php", затем накопится и затем перепишет тот файл.

Если я не буду ошибочным PHP, то обнаружит, что файл ("stats.php") изменяется, и загрузите новый. Корректный?

22
задан Poni 27 May 2010 в 15:47
поделиться

3 ответа

Что ж, большая часть PHP выполняется в другом пространстве процесса (существует несколько реализаций потоковой передачи). Самый легкий - это стадо. Гарантированно работает на всех платформах.

Однако, если вы компилируете с поддержкой, вы можете использовать еще несколько вещей, например, расширение Semaphore. (Скомпилируйте PHP с помощью --enable-sysvsem). Затем вы можете сделать что-то вроде (обратите внимание, sem_acquire () должен блокироваться. Но если по какой-то причине он не может этого сделать, он вернет false):

$sem = sem_get(1234, 1);
if (sem_acquire($sem)) {
    //successful lock, go ahead
    sem_release($sem);
} else {
    //Something went wrong...
}

Другие варианты, которые у вас есть, - это MySQL блокировки на уровне пользователя. GET_LOCK ('name', 'timeout') , или создание собственного с помощью чего-то вроде APC или XCache (обратите внимание, это не будет настоящей блокировкой, поскольку условия гонки могут быть созданы там, где кто-то другой получит между вашим чеком и принятием замка).

Edit: Чтобы ответить на ваш отредактированный вопрос:

Все зависит от конфигурации вашего сервера. PHP может выполняться в многопоточном режиме (где каждый запрос обслуживается отдельным потоком) или может выполняться в нескольких процессах (где каждый запрос обслуживается другим процессом). Все зависит от конфигурации вашего сервера ...

ОЧЕНЬ редко PHP обслуживает все запросы последовательно, и только один процесс (и один поток) обслуживает все запросы. Если вы используете CGI, то по умолчанию он многопроцессорный. Если вы используете FastCGI, скорее всего, это многопроцессорный и многопоточный. Если вы используете mod_php с Apache, это зависит от типа рабочего:

  1. mpm_worker будет как многопроцессорным, так и многопоточным, причем количество процессов определяется переменной ServerLimit.
  2. prefork будет многопроцессорным
  3. perchild будет многопроцессорным

Edit: Чтобы ответить на ваш второй отредактированный вопрос:

Это довольно просто. Сохраните его в файле:

function readStatus() {
    $f = fopen('/path/to/myfile', 'r');
    if (!$f) return false;
    if (flock($f, LOCK_SH)) {
        $ret = fread($f, 8192);
        flock($f, LOCK_UN);
        fclose($f);
        return $ret;
    }
    fclose($f);
    return false;
}

function updateStatus($new) {
    $f = fopen('/path/to/myfile', 'w');
    if (!$f) return false;
    if (flock($f, LOCK_EX)) {
        ftruncate($f, 0);
        fwrite($f, $new);
        flock($f, LOCK_UN);
        fclose($f);
        return true;
    }
    fclose($f);
    return false;
}

function incrementStatus() {
    $f = fopen('/path/to/myfile', 'rw');
    if (!$f) return false;
    if (flock($f, LOCK_EX)) {
        $current = fread($f, 8192);
        $current++;
        ftruncate($f, 0);
        fwrite($f, $current);
        flock($f, LOCK_UN);
        fclose($f);
        return true;
    }
    fclose($f);
    return false;
}
31
ответ дан 29 November 2019 в 05:18
поделиться

PHP не поддерживает многопоточность, каждый запрос (и, следовательно, каждый сценарий PHP) будет выполняться только в одном потоке (или даже в процессе, в зависимости от того, как вы запускаете PHP).

-2
ответ дан 29 November 2019 в 05:18
поделиться

Да, это правда, поскольку PHP управляется Apache, и Apache может организовать потоки выполнения так, как он считает лучшим (см. Различные рабочие модели). Поэтому, если вы хотите получить доступ к ресурсу по одному, вы либо блокируете файл (что хорошо, например, если вы имеете дело с заданиями cron), либо полагаетесь на механизм транзакций базы данных, функции ACID и блокировку ресурсов базы данных, если вы имеете дело с данными.

0
ответ дан 29 November 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: