Столкнулся с такой проблемой. Есть программа написанная на пхп. Все плагины она подгружает поочереди из одной папки. При создании для нее парочки новых плагинов столкнулся с проблемой. В одном из плагинов мне нужно поставить задержку выполнения одной из функций. Проблема в том что если ставить sleep() то происходит тормоз всего цикла и сообсна прога вся зависает на время в слипе. Еслть ли способ задержать чисто функцию, без задержки всего исполнения проги? Сообственно вот сам плагин. PHP: <?php function bannerrus_read() { global $bannerrus_bannerrus; $configdir = $GLOBALS['mod']->getConfigDir(); $bannerrus_bannerrus = explode("\n", file_get_contents($configdir . "/plugins/bannerrus.lst")); $bannerrus_bannerrus = array_map("trim", $bannerrus_bannerrus); } $bannerrus_lasttime = 0; $bannerrus_current = 0; $mod->registerEvent("everyTime", "bannerrus_send"); $mod->registerEvent("parseConfig", "bannerrus_read"); $mod->setDefaultCV("bannerrus", "enabled", 0); $mod->setDefaultCV("bannerrus", "time", 120); bannerrus_read(); function bannerrus_send() { global $bannerrus_bannerrus; global $bannerrus_lasttime; global $bannerrus_current; global $mod; global $logging; if (!$mod->getCV("bannerrus", "enabled")) { return false; } if (time() - $bannerrus_lasttime > $mod->getCV("bannerrus", "time")) { if ($bannerrus_current >= count($bannerrus_bannerrus)) { $bannerrus_current = 0; } $send = $bannerrus_bannerrus[$bannerrus_current]; if (strpos($send, "<NEXTMAP>") !== false || strpos($send, "<NEXTGT>") !== false) { list($nextmap, $nextgt) = $mod->rconGetNextMap(); $nextmap = $mod->getLongMapName($nextmap); $nextgt = $mod->getLongGametype($nextgt); $send = str_replace(array("<NEXTMAP>", "<NEXTGT>"), array($nextmap, $nextgt), $send); } $send = str_replace("<VERSION>", VERSION, $send); (ЗДЕСЬ НУЖНА ЗАДЕРЖКА ДЛЯ ФУНКЦИИ НИЖЕ) $mod->rconSay($send); $logging->write(MOD_NOTICE, "Bannerrus message was sent: ".$send); $bannerrus_lasttime = time(); $bannerrus_current ++; } } ?> Прошу прощения если не в тот раздел обратился.
Всмысле? Даже если его вынести как отдельный, то всеравно при подгрузке плагинов цикл в том месте затормозится. Причем содержимое етого плагина вызывается неоднокртано и как-то абсолютно душу не греют постоянные зависания связанные со слипом. Я тоже об етом думал, но увы....
Хм... Это всмысле разбить функцию паралельно от скрипта, т.е. чтобы действия выполнялись паралельно? Если да, то это сообственно то что мне нужно. К сожалению я без идей как это осуществить. Поможете? Могу предоставить любую информацию о программе и взаимодействии внутри нее,если нужно Вам нужно.
есть несколько вариантов реализации, погуглите на тему "php много поточность" там много всего и достаточно просто все вам будет быстрее разобраться какой вариант подходит или как изменить свой код, так чтобы подходило и можно ли такое вообще реализовать
Спасибо что-нибудь просмотрю. Я сам сомневаюсь в возможности реализации, но просто кажется вроде такая рутинная функция, и проблемы. Если что вернусь сюда.
ну будет плагин рапортовать об успехе и отдавать управление обратно, а паралельно надо запустить отдельным потоком ту штуку, которая через какое-то время сделает то, что нужно. как вариант, ввести в плагиновый движок централизованную возможность таймеров и всякого такого отсраченого.
не есть много поточность на уровне оси, как раз форк, а есть на уровне самого языка, которую php не поддерживает
хз. плагины штука мутная. если давать им полную свободу - надо выделять в отдельный процесс, и чтобы они не закрывались. либо центрально это все делать через API мол, хочу запуститься через 20 секунд - пожалуйста. все равно надо добиться, чтобы скрипт php работал много и долго. а это уже потенциально опасно... хз как быть.
Спасибо всем! Проблему решил, правда немного по другому. Т.к. оказалось что разветвление ето очень, скажем помягче, трудоемкий процесс, то я решил просто написать пару отдельных плагинов где сделал вывод этой функции опциональной. Вышло намного проще и еффективней. = ) Извините что доставил лишней головной боли. Просто думал уже над этим со вчерашнего дня - голова зациклилась. Немного свежих идей и отдыха помогло.
Хотя сообственно проблема не решилась. Я ее немножечко уменьшил, но к сожалению не ликвидирвоал как думал раньше. Суть скрипта вышеуказанного (кстати их таких 2 лиш с маленьки различием) - выводить сообщение через определенный интервал времени. (автоаносер аля такой). Вот нада помощь. Вводная - Оба скрипта написаны одинаково, а различие - из какого документа читать данные (один русский другой английский). Вот типа должно быть так - появляется 1 сообщение (1 скрипт) потом через n-ное время 2(2 скрипт). И потом каждое новое появляется с интервалом в х сек. Пример как оно должно выводится (с точки зрения времени а не алгоритма.) - 1 сообщ англ. - 0 сек (тобиш сразу при запуске) 2 сообщ рус. - n сек 3 сообщ англ. - 0+х сек 4 сообщ. рус - n + x сек 5 сообщ англ. - 0+х+х сек 6 сообщ. рус - n + x + х сек и т.д. Вот в чем загвоздка. Я не могу установить задержку появления сообщения 2 в самом начале на n сек.
Отдых - безценная вещь. Особенно взяв бумажку и ручку пришло осенение. Проблему РЕШИЛ! Я не обратил внимание на то, что $bannerrus_lasttime (строка 11 начального кода) задается в формате time(), что кстати прекрасно видно из предпоследнего ее вызова, где обнуляются счетчики (строка 61 начального кода). Я думал это интервальный промежуток. Соответственно присвоив переменной новое значение (строка 11 новый вариант) и потом просто отсинхронизировав по логам путем подстановки промежуток между сообщениями все получилось!!! Вот вообствено готовый код. Решил выложить - вдруг кому пригодится. Всем спасибо! PHP: <?php //bannerrus einlesen und die Zдhlvariablen auf 0 setzen function bannerrus_read() { global $bannerrus_bannerrus; $configdir = $GLOBALS['mod']->getConfigDir(); $bannerrus_bannerrus = explode("\n", file_get_contents($configdir . "/plugins/bannerrus.lst")); $bannerrus_bannerrus = array_map("trim", $bannerrus_bannerrus); } $bannerrus_lasttime = time() + (37); $bannerrus_current = 0; //Event registrieren $mod->registerEvent("everyTime", "bannerrus_send"); $mod->registerEvent("parseConfig", "bannerrus_read"); //Default CVs registrieren $mod->setDefaultCV("bannerrus", "enabled", 0); $mod->setDefaultCV("bannerrus", "time", 120); bannerrus_read(); //Funktion die bei jedem durchlauf aufgerufen wird function bannerrus_send() { global $bannerrus_bannerrus; global $bannerrus_lasttime; global $bannerrus_current; global $mod; global $logging; //Ist [bannerrus]enabled = 1 if (!$mod->getCV("bannerrus", "enabled")) { return false; } //Prьfen, wann der letzte bannerrus gesendet wurde und ggf. nдchsten senden if (time() - $bannerrus_lasttime > $mod->getCV("bannerrus", "time")) { //Zдhler ggf. zurьcksetzen, wenn EOF bei bannerrus.lst if ($bannerrus_current >= count($bannerrus_bannerrus)) { $bannerrus_current = 0; } $send = $bannerrus_bannerrus[$bannerrus_current]; //Is <NEXTMAP> or <NEXTGT> used if (strpos($send, "<NEXTMAP>") !== false || strpos($send, "<NEXTGT>") !== false) { list($nextmap, $nextgt) = $mod->rconGetNextMap(); $nextmap = $mod->getLongMapName($nextmap); $nextgt = $mod->getLongGametype($nextgt); $send = str_replace(array("<NEXTMAP>", "<NEXTGT>"), array($nextmap, $nextgt), $send); } $send = str_replace("<VERSION>", VERSION, $send); //bannerrus senden $mod->rconSay($send); $logging->write(MOD_NOTICE, "bannerrus message was sent: ".$send); //Zдhler erhцhen und Zeit neu setzen $bannerrus_lasttime = time(); $bannerrus_current ++; } } ?>