события — Может ли php.exe запускаться для приложений, которые работают неделями или месяцами вместе, непрерывно, без сбоев?

Может ли php.exe запускаться для приложений, которые работают неделями или месяцами, непрерывно, без сбоев?

Пример: приложение UDP или HTTP / TCP-сервер (или сеть). Я слышал, что он не был разработан для долго работающих приложений все время. Я считаю, что мы можем выполнять многопоточность / параллельность, используя pthreads / events как в Linux, так и в Windows, чтобы поддерживать нагрузку, создаваемую для процессов, и разрабатывать долго работающие приложения. Но не уверен, насколько стабильным это будет. Кто-нибудь, кто может прокомментировать и предоставить некоторые ресурсы для разработки с использованием pthreads и давно работающих приложений PHP?

0

Решение

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

<?php
class Foo
{
public $var = '3.14159265359';
}

$baseMemory = memory_get_usage();

for ( $i = 0; $i <= 100000; $i++ )
{
$a = new Foo;
$a->self = $a;
if ( $i % 500 === 0 )
{
echo sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "\n";
}
}
?>

Ниже приведено использование памяти для 5.2 и 5.3 бок о бок:

5,2 против 5,3 использование памяти

Это делает написание кода любой сложности, который выполняется бесконечно, настолько близок, насколько это невозможно в версиях PHP ниже 5.3.

Для версий PHP, равных или превышающих 5.3, в Zend нет абсолютно ничего, что запрещало бы выполнение долго выполняющихся сценариев, даже неограниченное выполнение.

Есть еще о чем подумать; Если вы бесконечно добавляете к какому-либо массиву, вам понадобится бесконечный объем памяти для хранения этого массива.

Нужно просто быть осторожным, даже безобидные изменения могут повлиять на потребление, поэтому установите шаблон частого регрессионного тестирования во время разработки, чтобы вы могли видеть, где проблемы возникают немедленно.

Код и изображение взято с Руководство по PHP.

Я собираюсь ответить в контексте pthreads v3, PHP7 +.

Pthreads может потреблять больше памяти, чем вы ожидаете. PHP — это среда без совместного использования ресурсов, pthreads не должна нарушать эту архитектуру, поэтому в отличие от обычного многопоточного приложения потоки не могут использовать одно и то же адресное пространство.

pthreads заставляет его выглядеть так, как будто он это делает, то, как он это делает, не важно для ответа.

С нормальным Thread программирование, потребление не должно быть так сложно контролировать, но с Worker а также Pool программирование, это может быть не так очевидно.

Возьмите следующий код:

<?php
class Job extends Threaded {
public function run() {
printf("Job in Thread %lu (%d) bytes\n",
Thread::getCurrentThreadId(),
memory_get_usage(false));
}
}

$pool = new Pool(16);
$monitor = new Threaded();

do {
for ($i=0; $i<100; $i++)
$pool->submit(new Job());

while ($pool->collect())
continue;

printf("Main context (%d) bytes\n",
memory_get_usage(false));

$monitor->synchronized(function() use($monitor) {
$monitor->wait(1000000);
});
} while (true);
?>

Звонки с использованием $monitor должно быть соглашение, самый хороший способ заставить ThreadДаже основной контекст, чтобы спать.

Если бы не звонки ::collect, потребление скоро выйдет из-под контроля.

::collect Метод на самом деле является частью Worker класс, Pool вызывает его по доверенности для всех Worker объекты, которые он использует.

Прототип можно принять за:

public function collect(callable $collector = Worker::collector);

Когда Job выталкивается из очереди для выполнения внутри Worker контекст, который его выполняет, вставляется в список мусора.

когда ::collect называется, список мусора для Worker пройдено, проходя каждый Job в $collector передан (или нет) в качестве аргумента.

Если Worker выполняет такую ​​работу, которая делает опасным сбор мусора в то время, призыв к ::collect вернется рано, и вы должны попробовать еще раз, если возвращаемое значение из ::collect > 0

$collector должен вернуть true, если Job может быть удален из списка мусора (следовательно, освобождает связанные ресурсы, если нет других ссылок), по умолчанию Worker::collector возвращается trueПредполагая, что объект в списке мусора готов к уничтожению при первой же возможности.

Все это позволяет долго работающим, довольно сложным приложениям на основе pthreads работать бесконечно.

Должны быть приняты те же соображения, что и для обычного PHP, с дополнительной (небольшой) работой.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]