За последние 24 часа нас посетил 18571 программист и 1683 робота. Сейчас ищет 1371 программист ...

Задержка выполнения фунции

Тема в разделе "PHP для новичков", создана пользователем VictDrag, 29 июн 2010.

  1. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Столкнулся с такой проблемой. Есть программа написанная на пхп. Все плагины она подгружает поочереди из одной папки. При создании для нее парочки новых плагинов столкнулся с проблемой. В одном из плагинов мне нужно поставить задержку выполнения одной из функций. Проблема в том что если ставить sleep() то происходит тормоз всего цикла и сообсна прога вся зависает на время в слипе. Еслть ли способ задержать чисто функцию, без задержки всего исполнения проги?
    Сообственно вот сам плагин.
    PHP:
    1. <?php
    2.  
    3.  
    4. function bannerrus_read() {
    5.     global $bannerrus_bannerrus;
    6.     $configdir = $GLOBALS['mod']->getConfigDir();
    7.     $bannerrus_bannerrus = explode("\n", file_get_contents($configdir . "/plugins/bannerrus.lst"));
    8.     $bannerrus_bannerrus = array_map("trim", $bannerrus_bannerrus);
    9. }
    10.  
    11. $bannerrus_lasttime = 0;
    12. $bannerrus_current = 0;
    13.  
    14.  
    15. $mod->registerEvent("everyTime", "bannerrus_send");
    16. $mod->registerEvent("parseConfig", "bannerrus_read");
    17.  
    18.  
    19. $mod->setDefaultCV("bannerrus", "enabled", 0);
    20. $mod->setDefaultCV("bannerrus", "time", 120);
    21.  
    22. bannerrus_read();
    23.  
    24.  
    25. function bannerrus_send() {
    26.     global $bannerrus_bannerrus;
    27.     global $bannerrus_lasttime;
    28.     global $bannerrus_current;
    29.     global $mod;
    30.     global $logging;
    31.  
    32.    
    33.     if (!$mod->getCV("bannerrus", "enabled")) {
    34.         return false;
    35.     }
    36.  
    37.    
    38.     if (time() - $bannerrus_lasttime > $mod->getCV("bannerrus", "time")) {
    39.  
    40.        
    41.         if ($bannerrus_current >= count($bannerrus_bannerrus)) {
    42.             $bannerrus_current = 0;
    43.         }
    44.  
    45.         $send = $bannerrus_bannerrus[$bannerrus_current];
    46.  
    47.        
    48.         if (strpos($send, "<NEXTMAP>") !== false || strpos($send, "<NEXTGT>") !== false) {
    49.             list($nextmap, $nextgt) = $mod->rconGetNextMap();
    50.             $nextmap = $mod->getLongMapName($nextmap);
    51.             $nextgt = $mod->getLongGametype($nextgt);
    52.             $send = str_replace(array("<NEXTMAP>", "<NEXTGT>"), array($nextmap, $nextgt), $send);
    53.         }
    54.         $send = str_replace("<VERSION>", VERSION, $send);
    55.        
    56.                             (ЗДЕСЬ НУЖНА ЗАДЕРЖКА ДЛЯ ФУНКЦИИ НИЖЕ)
    57.         $mod->rconSay($send);
    58.         $logging->write(MOD_NOTICE, "Bannerrus message was sent: ".$send);
    59.  
    60.        
    61.                             $bannerrus_lasttime = time();
    62.         $bannerrus_current ++;
    63.     }
    64.  
    65. }
    66.  
    67. ?>

    Прошу прощения если не в тот раздел обратился.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    пускать его в отдельном процессе, видимо.
     
  3. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Всмысле? Даже если его вынести как отдельный, то всеравно при подгрузке плагинов цикл в том месте затормозится. Причем содержимое етого плагина вызывается неоднокртано и как-то абсолютно душу не греют постоянные зависания связанные со слипом. Я тоже об етом думал, но увы....
     
  4. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    не смог проникнуться логикой, какой то странный код, много поточность не поможет тут?
     
  5. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Хм... Это всмысле разбить функцию паралельно от скрипта, т.е. чтобы действия выполнялись паралельно? Если да, то это сообственно то что мне нужно. К сожалению я без идей как это осуществить. Поможете?

    Могу предоставить любую информацию о программе и взаимодействии внутри нее,если нужно Вам нужно.
     
  6. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    есть несколько вариантов реализации, погуглите на тему "php много поточность" там много всего и достаточно просто все
    вам будет быстрее разобраться какой вариант подходит или как изменить свой код, так чтобы подходило и можно ли такое вообще реализовать
     
  7. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Спасибо что-нибудь просмотрю. Я сам сомневаюсь в возможности реализации, но просто кажется вроде такая рутинная функция, и проблемы. Если что вернусь сюда.
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ну будет плагин рапортовать об успехе и отдавать управление обратно, а паралельно надо запустить отдельным потоком ту штуку, которая через какое-то время сделает то, что нужно.

    как вариант, ввести в плагиновый движок централизованную возможность таймеров и всякого такого отсраченого.
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
  10. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    не есть много поточность на уровне оси, как раз форк, а есть на уровне самого языка, которую php не поддерживает
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    хз.
    плагины штука мутная. если давать им полную свободу - надо выделять в отдельный процесс, и чтобы они не закрывались. либо центрально это все делать через API мол, хочу запуститься через 20 секунд - пожалуйста.
    все равно надо добиться, чтобы скрипт php работал много и долго. а это уже потенциально опасно...

    хз как быть.
     
  12. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Спасибо всем! Проблему решил, правда немного по другому. Т.к. оказалось что разветвление ето очень, скажем помягче, трудоемкий процесс, то я решил просто написать пару отдельных плагинов где сделал вывод этой функции опциональной. Вышло намного проще и еффективней. = )
    Извините что доставил лишней головной боли. Просто думал уже над этим со вчерашнего дня - голова зациклилась. Немного свежих идей и отдыха помогло.
     
  13. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Хотя сообственно проблема не решилась. Я ее немножечко уменьшил, но к сожалению не ликвидирвоал как думал раньше.




    Суть скрипта вышеуказанного (кстати их таких 2 лиш с маленьки различием) - выводить сообщение через определенный интервал времени. (автоаносер аля такой). Вот нада помощь. Вводная -
    Оба скрипта написаны одинаково, а различие - из какого документа читать данные (один русский другой английский).
    Вот типа должно быть так - появляется 1 сообщение (1 скрипт) потом через n-ное время 2(2 скрипт). И потом каждое новое появляется с интервалом в х сек. Пример как оно должно выводится (с точки зрения времени а не алгоритма.) -
    1 сообщ англ. - 0 сек (тобиш сразу при запуске)
    2 сообщ рус. - n сек
    3 сообщ англ. - 0+х сек
    4 сообщ. рус - n + x сек
    5 сообщ англ. - 0+х+х сек
    6 сообщ. рус - n + x + х сек
    и т.д.
    Вот в чем загвоздка. Я не могу установить задержку появления сообщения 2 в самом начале на n сек.
     
  14. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    решили проблему?
     
  15. VictDrag

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

    С нами с:
    29 июн 2010
    Сообщения:
    9
    Симпатии:
    0
    Отдых - безценная вещь. Особенно взяв бумажку и ручку пришло осенение. Проблему РЕШИЛ!
    Я не обратил внимание на то, что $bannerrus_lasttime (строка 11 начального кода) задается в формате time(), что кстати прекрасно видно из предпоследнего ее вызова, где обнуляются счетчики (строка 61 начального кода). Я думал это интервальный промежуток.
    Соответственно присвоив переменной новое значение (строка 11 новый вариант) и потом просто отсинхронизировав по логам путем подстановки промежуток между сообщениями все получилось!!! Вот вообствено готовый код. Решил выложить - вдруг кому пригодится. Всем спасибо!


    PHP:
    1. <?php
    2.  
    3. //bannerrus einlesen und die Zдhlvariablen auf 0 setzen
    4. function bannerrus_read() {
    5.     global $bannerrus_bannerrus;
    6.     $configdir = $GLOBALS['mod']->getConfigDir();
    7.     $bannerrus_bannerrus = explode("\n", file_get_contents($configdir . "/plugins/bannerrus.lst"));
    8.     $bannerrus_bannerrus = array_map("trim", $bannerrus_bannerrus);
    9. }
    10.  
    11. $bannerrus_lasttime = time() + (37);
    12. $bannerrus_current = 0;
    13.  
    14. //Event registrieren
    15. $mod->registerEvent("everyTime", "bannerrus_send");
    16. $mod->registerEvent("parseConfig", "bannerrus_read");
    17.  
    18. //Default CVs registrieren
    19. $mod->setDefaultCV("bannerrus", "enabled", 0);
    20. $mod->setDefaultCV("bannerrus", "time", 120);
    21.  
    22. bannerrus_read();
    23.  
    24. //Funktion die bei jedem durchlauf aufgerufen wird
    25. function bannerrus_send() {
    26.     global $bannerrus_bannerrus;
    27.     global $bannerrus_lasttime;
    28.     global $bannerrus_current;
    29.     global $mod;
    30.     global $logging;
    31.  
    32.     //Ist [bannerrus]enabled = 1
    33.     if (!$mod->getCV("bannerrus", "enabled")) {
    34.         return false;
    35.     }
    36.  
    37.     //Prьfen, wann der letzte bannerrus gesendet wurde und ggf. nдchsten senden
    38.     if (time() - $bannerrus_lasttime > $mod->getCV("bannerrus", "time")) {
    39.  
    40.         //Zдhler ggf. zurьcksetzen, wenn EOF bei bannerrus.lst
    41.         if ($bannerrus_current >= count($bannerrus_bannerrus)) {
    42.             $bannerrus_current = 0;
    43.         }
    44.  
    45.         $send = $bannerrus_bannerrus[$bannerrus_current];
    46.  
    47.         //Is <NEXTMAP> or <NEXTGT> used
    48.         if (strpos($send, "<NEXTMAP>") !== false || strpos($send, "<NEXTGT>") !== false) {
    49.             list($nextmap, $nextgt) = $mod->rconGetNextMap();
    50.             $nextmap = $mod->getLongMapName($nextmap);
    51.             $nextgt = $mod->getLongGametype($nextgt);
    52.             $send = str_replace(array("<NEXTMAP>", "<NEXTGT>"), array($nextmap, $nextgt), $send);
    53.         }
    54.         $send = str_replace("<VERSION>", VERSION, $send);
    55.  
    56.         //bannerrus senden
    57.         $mod->rconSay($send);
    58.         $logging->write(MOD_NOTICE, "bannerrus message was sent: ".$send);
    59.  
    60.         //Zдhler erhцhen und Zeit neu setzen
    61.         $bannerrus_lasttime = time();
    62.         $bannerrus_current ++;
    63.     }
    64.  
    65. }
    66.  
    67. ?>
    68.