За последние 24 часа нас посетили 15157 программистов и 1671 робот. Сейчас ищут 978 программистов ...

Существуют ли альтернативы функции flock()?

Тема в разделе "Прочие вопросы по PHP", создана пользователем oleg_sys, 30 ноя 2008.

  1. oleg_sys

    oleg_sys Активный пользователь

    С нами с:
    30 ноя 2008
    Сообщения:
    3
    Симпатии:
    0
    проблема такая:

    есть сайт c большой посещаемостью. мне нужно подсчитывать количество уникальных ip которые зашли на определенную страницу.

    сначала я написал скрипт, который работает с файлом. чтобы предотвратить ошибки я перед записью и чтением блокировал его функцией flock. но спустя некоторое время почему-то иногда возникали ошибки.
    например:

    123.123.23.22
    123.123.23.22
    123.123.23.22
    123.12
    55.883.23.22
    123.123.23.22
    123.123.23.22
    123.123.23.22
    123.123.23.22

    я понял что функция flock не идеальная для моей задачи и переписал скрипт на работу с мускулем. использовал функцию:

    Код (Text):
    1.   $res = mysql_query("select GET_LOCK('my_lock',3)");
    она работает без ошибок.

    но я хочу все-таки отказаться от мускула для этой задачи.

    Существуют ли какието альтернативы функции flock() ?
    ps я слышал про какието "файлы-флаги" но информации о них не нашел.

    спасибо!
     
  2. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    я бы наоборот, отказался от файлов
     
  3. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    flock не врет.
    Скорее всего ошибка в вашем скрипте.
    Покажите как лочите файл.
    На какой файловой системе проблема?

    Идея проста.
    Перед работой с файлом пытаемся создать "файл-флаг".
    Если удалось - работаем с файлом, иначе - другой скрипт еще не закончил работу с этим файлом.
    PHP:
    1. <?
    2. $fn = 'my file';
    3. $lockFn = "$fn.lock";
    4. $lockFile = @fopen($lock, 'x');
    5. if ($lock) {
    6.    // работаем с файлом $fn
    7.    fclose($lockFile);
    8.    unlink($lockFn);
    9. }
    10. else {
    11.    // файл залочен. отдаем ошибку или спим и пробуем снова
    12. }
    Не сложно представить что будет, если скрипт упадет и не удалит "файл-флаг".
     
  4. oleg_sys

    oleg_sys Активный пользователь

    С нами с:
    30 ноя 2008
    Сообщения:
    3
    Симпатии:
    0
    я старый скрипт стер. принцип такой:


    $fp = fopen("list.txt", 'a');
    if ($fp)
    {
    flock($fp, LOCK_EX);
    fputs($fp, "12345");
    flock($fp, LOCK_UN);
    fclose($fp);
    }

    файловая система не помню какая (доступ к серверу только из офиса) но стоит ОС сентоз 5.

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

    я протестирую ваш код но боюсь что проблема повторится. чтобы протестировать достаточно сгенерировать трафик в 100 потоков которые будут вызывать этот скрипт :)
     
  5. oleg_sys

    oleg_sys Активный пользователь

    С нами с:
    30 ноя 2008
    Сообщения:
    3
    Симпатии:
    0
    дело в том что весь контент сайта хранится в текстовых файлах и юзать мускул только изза счетсчика помоему не рационально.
     
  6. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    А парсинг access лога apache/lighttpd/nginx не катит?
     
  7. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    копипаст с сорцов книги PHP5 Котеров.
    PHP:
    1. <?php ## Модель процесса-писателя.
    2. $file = "file.txt";
    3.  
    4. // Вначале создаем пустой файл, ЕСЛИ ЕГО ЕЩЕ НЕТ.
    5. // Если же файл существует, это его не разрушит.
    6. fclose(fopen($file, "a+b"));
    7.  
    8. // Блокируем файл.
    9. $f = fopen($file, "r+b") or die("Не могу открыть файл!");
    10. flock($f, LOCK_EX); // ждем, пока мы не станем единственными
    11.  
    12.   // . . .
    13.   // В этой точке мы можем быть уверены, что только эта
    14.   // программа работает с файлом.
    15.   // . . .
    16.  
    17. // Все сделано. Снимаем блокировку.
    18. fclose($f);
    19.  
    На сколько я помню, важна строка 6.
    Так же, со вторым аргументом fopen 'a' и 'a+' какие-то траблы.
    Попробуйте.
     
  8. sword dancer

    sword dancer Активный пользователь

    С нами с:
    17 фев 2008
    Сообщения:
    295
    Симпатии:
    0
  9. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Значить, если в файл пишется только IP в 'a' режиме - никаких флоков вообще не нужно