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-сервер обновляет свою статистику, а другой тоже делает это, информация будет смешанной.
Как при многопоточности; Два потока одновременно увеличивают некоторую переменную «int». Это произойдет не так, как ожидалось, если вы не синхронизируете между ними.
Итак, у меня будет проблема? Да нет Может быть?

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

Мы много размышляем об этом весь день, у меня есть идея здесь, и я хочу, чтобы вы дали свое мнение.
Как сказано, эти ftp-серверы будут публиковать свою статистику каждые раз в 60 секунд.
Я думаю о том, что этот файл «stats.php».
Он будет включен в скрипт обновления, который серверы ftp перейдут («update.php») и на страницу «index.php», где посетители видят, сколько пользователей подключено к сети.
Теперь, когда сервер ftp обновляется, скрипт на «update.php» будет изменять «stats.php» с новой совокупной статистикой.
Сначала он будет читать статистику, включенную в «stats.php», а затем накапливать, а затем переписать этот файл.

Если я не ошибаюсь, PHP обнаружит, что файл («stats.php») изменен и загружает новый. Верный?

Related of "PHP взаимное исключение (мьютекс)"

Наилучшим образом, большая часть 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 (обратите внимание: это не будет истинной блокировкой, поскольку условия гонки могут быть созданный там, где кто-то получает блокировку между проверкой и принятием блокировки).

Изменить: Чтобы ответить на отредактированный вопрос:

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

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

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

Изменить: Чтобы ответить на второй отредактированный вопрос:

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

 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; } 

Возникает вопрос: где вы будете хранить статистику, которую FTP-серверы нажимают с помощью POST в файл update.php? Если это локальный файл, на ваш ответ ответит ircmaxell во втором сообщении. Вы можете сделать это с помощью мьютекса – функции семафора. Другое решение – использовать таблицу MySQL MyISAM для хранения статистики и использовать что-то вроде update info_table set value = value + 1 . Он должен блокировать таблицу и сериализовать ваши запросы, и у вас не будет проблем.

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

Если вам нужна потоковая передача, вы серьезно относитесь к неправильному языку.

Почему бы вам просто не записать файл обновления в имя файла на основе ipaddress входящего ftp-сервера. И файл php статистики просто читает и добавляет числовое содержимое обоих этих файлов вместе.

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