Доступ к синхронизированным файлам PHP 5.x (без базы данных)

Я в основном знаком с Java, C и C++, в которых есть способы контролировать, чтобы только один поток обращался к ресурсу в любой момент времени. Сейчас ищу что-то похожее, но на PHP 5.x.

Чтобы сформулировать мою проблему на одном примере:

У меня есть ASCII-файл, в котором хранится только число, значение счетчика загрузки страницы. При развертывании приложения файл просто будет содержать 0. Для каждого доступа значение будет увеличиваться на единицу. Цель - отслеживать загрузку страниц.

Проблема возникает, когда многие пользователи одновременно обращаются к странице, содержащей счетчик. Когда поток A прочитал текущее значение, допустим, это 11, другой поток, который мы называем B, считывает значение, по-прежнему 11. Затем первый поток A увеличивает значение чтения и записывает 12 в файл и закрывает его. Затем второй поток B увеличивает значение чтения, которое было 11, получает 12 и записывает его в файл. В файле хранится значение 12, тогда как на самом деле должно было быть 13.

На другом языке программирования я бы решил это с помощью мьютекса. Я так понимаю, что в составе модулей есть мьютексы, разделяемая память и другие функции. Но мне нужно решение, которое работает «на большинстве серверов». Независимая платформа. Устанавливается на самых дешевых веб-хостингах. Есть ли хорошее решение этой проблемы? А если нет, то какой путь вы выберете при использовании база данных не вариант?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
6
0
1 497
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете попробовать php-вариант flock (http://www.php.net/flock)

Я бы вообразил что-то похожее (это предполагает, что файл /tmp/counter.txt уже существует и имеет счетчик в файле):

<?php

$fp = fopen("/tmp/counter.txt", "r+");

echo "Attempt to lock\n";
if (flock($fp, LOCK_EX)) {
  echo "Locked\n";
  // Read current value of the counter and increment
  $cntr = fread($fp, 80);
  $cntr = intval($cntr) + 1;

  // Pause to prove that race condition doesn't exist
  sleep(5);

  // Write new value to the file
  ftruncate($fp, 0);
  fseek($fp, 0, SEEK_SET);
  fwrite($fp, $cntr);
  flock($fp, LOCK_UN); // release the lock
  fclose($fp);
}

?>

Информативный ответ с решением примера проблемы, спасибо! Я думаю, что вызов flock ($ fp, LOCK_UN) хорош, хотя fclose ($ fp) также снимает блокировку. У меня есть один вопрос: почему вы добавляете пробелы перед новой строкой в ​​fwrite ($ fp, $ cntr. "\ N")?

user14070 11.10.2008 14:48

Ой, это остаток моей первоначальной разработки. Я собирался просто использовать fseek без ftruncate. Добавление пробелов гарантирует, что он удалит любые другие символы, которые были в строке (что более важно для уменьшения.) Отредактировано выше, поскольку оно больше не требуется.

terson 11.10.2008 21:03

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

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

Другие вопросы по теме