Некоторые люди, не будем показывать на них пальцем, считают, что PHP не умеет в параллельные вычисления. Однако, это не так. Я сделал несколько примеров того, как можно рассчитать число PI в несколько потоков, используя только стандартные средства PHP:
- Example1 - Реализация на форках с внешней обработкой данных
- Example2 - Реализация на форках с внутренней обработкой данных
- Example3 - Реализация на подпроцессах с внутренней обработкой данных
- Example4 - Реализация через tcp-сервер
Самый простой способ зародить параллельный процесс в PHP, это, конечно, вызвать функцию
pcntl_fork(). Она скопирует полностью то, что уже находится в рабочей памяти текущего
процесса, и вернёт 0 (для нового процесса) или идентификатор нового процесса (для родителя).
А дальше - дело техники, как это обработать. Единственное, на что нужно обратить внимание,
это подключение к базе данных. Его лучше не копировать, иначе оно сломается везде при
завершении дочернего процесса.
Ещё можно запускать параллельные процессы через функцию proc_open(). Она ничего не копирует,
а просто запускает процесс в фоновом режиме. При желании можно обмениваться данными с дочерним
процессом через потоки ввода-вывода.
И, пожалуй, самый экзотический вариант для PHP, это запуск обработки через tcp-сервер. В этом случае, правда, надо позаботиться о том, как запускать клиентов. Но при этом их можно запускать где угодно.
Тест производительности на i5-3470 CPU @ 3.20GHz в 4 потока, 10 миллионов точек:
| Файл | Технология | Точек в секунду |
|---|---|---|
| example1.php | fork | 2,516,915 |
| example2.php | fork | 2,491,067 |
| example3.php | proc_open | 2,232,290 |
| example4.php | tcp-server | 2,422,824 |
Плюс-минус все примеры работают одинаково. Но, если нужна реальная производительность, используйте
golang, он считает это же PI в 80 раз быстрее и, по слухам, там есть встроенная поддержка параллельности.