Многопоточность / Параллельная обработка в PHP - PullRequest
2 голосов
/ 21 апреля 2010

У меня есть PHP-скрипт, который будет генерировать отчет с использованием PHPExcel из данных, запрашиваемых из БД MySQL. В настоящее время он является линейным в обработке в том смысле, что он возвращает данные из MySQL, читает в шаблоне Excel, записывает данные в шаблон и выводит их. Я оптимизировал код до такой степени, что данные повторяются только один раз, и на стороне PHP выполняется очень мало обработки. Запрос возвращает сотни строк менее чем за 0,001 секунды, поэтому он выполняется достаточно быстро. Через некоторое время я обнаружил, что мои узкие места (удивление, удивление) читают шаблон и пишут вывод. Я хотел бы сделать это:

Spawn a thread/process to read the template
Spawn a thread/process to fetch the data
Return back to parent thread - Parent thread will wait until both are complete
Proceed on as normal

Мои основные вопросы: возможно ли это, оно того стоит? Если да обоим, как бы вы занялись этим? Также это PHP 5 на CentOS

Ответы [ 6 ]

8 голосов
/ 21 апреля 2010

Как правило, не рекомендуется создавать процесс Apache. Это может привести к неопределенным результатам. Вместо этого предпочтительнее использовать какой-либо механизм организации очередей. Gearman - это механизм организации очередей с открытым исходным кодом, который вы можете использовать. У меня также есть запись в блоге в очереди заданий Zend Server, в которой говорится о асинхронном выполнении задач Вы в очереди? Введение в очередь заданий Zend Server .

Вы также можете использовать что-то вроде классов очереди Zend Framework для реализации некоторой асинхронной работы. Zend_Queue

@ Swisstack, я также не согласен с вашим утверждением, что PHP не создан для высокой производительности. Очень редко языковые особенности являются причиной низкой производительности. Возможно, выполнив тест исходного языка, сравнивающий $ a ++ между различными языками, вы увидите это, но этот тип тестирования не имеет значения. Я несколько лет консультировался по PHP и никогда не видел проблем с производительностью, связанных с языком.

1 голос
/ 21 апреля 2010

Если и чтение шаблона, и запрос базы данных были медленными, то я бы сказал, что есть неплохой шанс, что достойная производительность может быть достигнута при параллельном выполнении задач. Но вы сказали это сами, чтение шаблона идет медленно, а запрос БД - быстрый. Таким образом, даже игнорируя любые дополнительные издержки, создаваемые добавлением, необходимым для параллельного выполнения задач, в лучшем случае вы экономите 0,001 секунды (время, необходимое для запроса базы данных).

Параллельное выполнение нескольких задач всегда будет требовать времени самой медленной задачи. Выполнение задач последовательно - это сумма всех задач. В вашем случае, templateTime + queryTime (0.001)

Не стоит имо.

Обычно база данных - это черепаха в уравнении. Вы можете выполнить эту часть асинхронно без особых усилий. См. Недавно добавленные функции mysqli_poll () и friend.

1 голос
/ 21 апреля 2010

Вы не можете многопоточность, но вы можете форк ( pcntl_fork , pcntl_wait ). Я уверен, что вам нужно тщательно протестировать время порождения процесса, чтобы убедиться, что оно того стоит в вашей ситуации.

$pid = pcntl_fork();

if ($pid == -1) {
  // fork failed

} elseif ($pid > 0) {
  // we're the parent! Wait for child to finish
  pcntl_waitpid($pid);

} else {
  // we're the child
}
1 голос
/ 21 апреля 2010

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

0 голосов
/ 26 апреля 2010

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

0 голосов
/ 21 апреля 2010

Вы можете определенно порождать процессы в CentOS с помощью PHP (http://php.net/manual/en/function.pcntl-fork.php). Прежде чем сделать это, я бы рассмотрел хотя бы одну вещь ... Если узкое место возникает при чтении шаблона и записи выходных данных, это это может быть только проблема, связанная с вводом / выводом, и поэтому работа с несколькими процессами может не сильно помочь ... Лично я бы попытался выяснить, возможно ли вместо этого выполнить некоторое кэширование ...

...