Шаблоны для PHP много процессов? - PullRequest
7 голосов
/ 20 января 2010

Какой шаблон проектирования существует для реализации выполнения некоторых процессов PHP и сбора результатов в одном процессе PHP?

Справочная информация:
У меня есть много больших деревьев (> 10000 записей) в PHP, и я должен выполнить рекурсивные проверки на нем. Я хочу сократить истекшее время выполнения.

Ответы [ 7 ]

11 голосов
/ 20 января 2010

Из вашего php-скрипта вы можете запустить другой скрипт (используя exec) для выполнения обработки.Сохраните обновления статуса в текстовом файле, который затем может периодически считываться родительским потоком.

Примечание: чтобы избежать php-ожидания завершения сценария exec 'd, передайте вывод в файл:

exec('/path/to/file.php | output.log');

В качестве альтернативы вы можете разветвлять скрипт, используя функции PCNTL .При этом используется один скрипт php, который при разветвлении может определить, является ли он родительским или дочерним, и работает соответственно.Существуют функции для отправки / получения сигналов с целью обмена данными между родителем / ребенком, или у вас есть дочерний журнал в файл, и родительский файл считан из этого файла.

Из pcntl_fork страница справочника:

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}
9 голосов
/ 01 февраля 2010

Если ваша цель - минимальное время - решение просто описать, но не так просто реализовать.

Вам нужно найти схему для разделения работы (вы не предоставили много информации в этом вопросе).

Затем используйте один мастер-процесс, который разветвляет детей, чтобы выполнить работу. Как правило, общее количество процессов, которые вы используете, должно быть между n и 2n, где n - это количество ядер, которое имеет машина.

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

Если вы решите не использовать select - может помочь увеличение числа процессов.


Относительно функций pcntl: я написал им демон (подходящий с разветвлением, изменением идентификатора сеанса, запущенным пользователем и т. Д.), И это одна из самых надежных программ, которые я написал. Поскольку он порождает рабочих для каждой задачи, даже если в одной из задач есть ошибка, она не влияет на другие.

4 голосов
/ 20 января 2010

Возможно, стоит подумать об использовании очереди сообщений , даже если вы запустите все на одной машине.

3 голосов
/ 01 февраля 2010

Вы можете использовать более эффективную структуру данных, такую ​​как btree. Я использовал один раз в Java, но не в PHP. Вы можете попробовать этот скрипт: http://www.phpclasses.org/browse/file/708.html, это реализация btree.

Если этого недостаточно, вы можете использовать Hadoop для реализации шаблона Map / Reduce, как сказал Майкл. Я бы не стал форк PHP-процесса, он, кажется, не помогает для производительности.

Лично я бы использовал PHP в качестве клиента и поместил бы все в Hadoop. Этот учебник может помочь: http://www.lunchpauze.com/2007/10/writing-hadoop-mapreduce-program-in-php.html.

Другим решением может быть использование Java-реализации Btree: http://jdbm.sourceforge.net/. JDBM - это объектная база данных, использующая структуры данных Btree +. Затем вы можете выполнять поиск с помощью PHP, предоставляя данные с помощью веб-службы или обращаясь к ним напрямую с помощью Quercus

.
2 голосов
/ 01 февраля 2010

Вопрос кажется немного запутанным.

Я хочу сократить абсолютное время выполнения.

Вы имеете в виду прошедшее время? Конечно, использование правильной структуры данных улучшит пропускную способность, но для данной структуры данных минимальный порядок алгоритма является абсолютным и не имеет ничего общего с тем, как вы реализуете алгоритм.

Какой шаблон проектирования существует для реализации ....?

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

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

В ответ на предложение Адама о разветвлении вы ответили:

Я "слышал", что pcntl не является хорошим решением. Есть опыт?

Где ты это услышал? Конечно, разветвление из вызываемого скрипта CGI или mod_php - плохая идея, но нет ничего плохого в том, чтобы делать это из командной строки. У вас есть Google для длительных процессов PHP (имейте в виду, что там много плохой информации). Какой код вы напишите, будет зависеть от операционной системы, которую вы не указали.

Я подозреваю, что вы могли бы решить большую часть проблем с производительностью, указав, какие части дерева необходимо проверить, и проверив только эти части И запустив проверки при обновлении дерева, или, по крайней мере, пометив узлы как ' грязный».

Вы могли бы найти это полезным:

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ http://en.wikipedia.org/wiki/Threaded_binary_tree

С

2 голосов
/ 29 января 2010

Использование веб-интерфейса или интерфейса командной строки?

Если вы используете веб, вы можете интегрировать эту часть в Quercus Тогда вы сможете использовать преимущества многопоточности JAVA.

На самом деле я не знаю, насколько надежен Quercus. Я бы также предложил использовать своего рода очередь сообщений и рефакторинг кода, чтобы он не нуждался в объеме.

Может быть, вы могли бы перестроить код в шаблон Map / Reduce. Затем вы можете запустить код PHP в Hadoop. Затем вы можете кластеризовать обработку на нескольких машинах.

Не знаю, полезно ли это, но я наткнулся на другой проект, который называется Gearman . Он также используется для кластеризации процессов PHP. Я полагаю, что вы можете комбинировать это и со скриптом сокращения, если Hadoop не тот путь, которым вы хотите.

0 голосов
/ 23 октября 2015

Pthreads

Доступно довольно новое (с 2012 года) расширение PHP: pthreads . Может быть установлен через PECL .

Простая реализация в коде PHP: расширение от Thread Класс. Добавьте метод run() и выполните метод start().

<?php
// Example from http://www.phpgangsta.de/richtige-threads-in-php-einfach-erstellen-mit-pthreads
class AsyncOperation extends Thread
{
    public function __construct($threadId)
    {
        $this->threadId = $threadId;
    }

    public function run()
    {
        printf("T %s: Sleeping 3sec\n", $this->threadId);
        sleep(3);
        printf("T %s: Hello World\n", $this->threadId);
    }
}

$start = microtime(true);
for ($i = 1; $i <= 5; $i++) {
    $t[$i] = new AsyncOperation($i);
    $t[$i]->start();
}
echo microtime(true) - $start . "\n";
echo "end\n";

Выходы

>php pthreads.php
0.041301012039185
end
T 1: Sleeping 3sec
T 2: Sleeping 3sec
T 3: Sleeping 3sec
T 4: Sleeping 3sec
T 5: Sleeping 3sec
T 1: Hello World
T 2: Hello World
T 3: Hello World
T 4: Hello World
T 5: Hello World
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...