Простой класс на PHP 7.2+, позволяющий выполнять задачи в нескольких параллельных потоках исполнения при помощи PHP-расширения parallel.
Docker-образ для быстрой проверки примера находится в репозитории на Docker Hub.
- PHP >=7.2 Thread Safe.
- PHP-расширение parallel.
- Произвольный автозагрузчик классов, реализующий стандарт PSR-4.
Установка через composer:
$ composer require andrey-tech/parallel-executor:"^1.0"
или добавить
"andrey-tech/parallel-executor": "^1.0"
в секцию require файла composer.json.
__construct(int $threads = 5, string $channelName = __CLASS__, int $channelСapacity = Channel::Infinite)
Конструктор класса.$threads
- количество создаваемых сред исполнения, как отдельных потоков PHP;$channelName
- имя создаваемого именованного канала;$channelСapacity
- емкость создаваемого именованного канала, МиБ (0 - небуферизированный канал)
execute(\Closure $closure, array $argv = []) :void
Отправляет на исполнение переданную задачу.$closure
- функция-замыкание, исполняющяя задачу;$argv
- аргументы функции.
Дополнительные параметры устанавливаются через публичные статические свойства класса \App\ParallelExecutor
:
Свойство | По умолчанию | Описание |
---|---|---|
$autoloader |
'' | Устанавливает файл автозагрузчика классов, подключаемый в каждой среде исполнения |
Выполнение 10 задач в 3 параллельных потоках PHP с буферизированным каналом:
// Создаем исполнитель c 3-я отдельными параллельными потоками PHP и буферизированным каналом
$executor = new \App\ParallelExecutor(3);
$i = 0;
$startTime = microtime(true);
while ($i < 10) {
$i++;
printf("[%.4f] execute" . PHP_EOL, microtime(true) - $startTime, $i);
$executor->execute(
function ($i) use ($startTime) {
$sleep = random_int(1, 5);
printf("[%.4f] %2d: Start sleeping {$sleep} s..." . PHP_EOL, microtime(true) - $startTime, $i);
sleep($sleep);
printf("[%.4f] %2d: DONE" . PHP_EOL, microtime(true) - $startTime, $i);
},
[ $i ]
);
}
Результат:
[0.0000] execute
[0.0001] execute
[0.0002] execute
[0.0002] 1: Start sleeping 5 s...
[0.0002] execute
[0.0003] 2: Start sleeping 4 s...
[0.0003] execute
[0.0003] 3: Start sleeping 5 s...
[0.0003] execute
[0.0004] execute
[0.0004] execute
[0.0004] execute
[0.0005] execute
[4.0008] 2: DONE
[4.0010] 4: Start sleeping 4 s...
[5.0005] 3: DONE
[5.0005] 1: DONE
[5.0007] 5: Start sleeping 5 s...
[5.0008] 6: Start sleeping 1 s...
[6.0020] 6: DONE
[6.0022] 7: Start sleeping 4 s...
[8.0016] 4: DONE
[8.0018] 8: Start sleeping 1 s...
[9.0023] 8: DONE
[9.0025] 9: Start sleeping 5 s...
[10.0014] 5: DONE
[10.0015] 10: Start sleeping 2 s...
[10.0026] 7: DONE
[12.0017] 10: DONE
[14.0036] 9: DONE
Выполнение 10 задач в 3 параллельных потоках PHP с НЕ буферизированным каналом:
// Создаем исполнитель c 3-я отдельными параллельными потоками PHP и НЕ буферизированным каналом
$executor = new \App\ParallelExecutor(3, 'taskChannel', 0);
$i = 0;
$startTime = microtime(true);
while ($i < 10) {
$i++;
printf("[%.4f] execute" . PHP_EOL, microtime(true) - $startTime, $i);
$executor->execute(
function ($i) use ($startTime) {
$sleep = random_int(1, 5);
printf("[%.4f] %2d: Start sleeping {$sleep} s..." . PHP_EOL, microtime(true) - $startTime, $i);
sleep($sleep);
printf("[%.4f] %2d: DONE" . PHP_EOL, microtime(true) - $startTime, $i);
},
[ $i ]
);
}
Результат:
[0.0000] execute
[0.0002] 1: Start sleeping 2 s...
[0.0002] execute
[0.0003] 2: Start sleeping 3 s...
[0.0004] execute
[0.0005] 3: Start sleeping 4 s...
[0.0005] execute
[2.0008] 1: DONE
[2.0009] 4: Start sleeping 5 s...
[2.0010] execute
[3.0006] 2: DONE
[3.0007] 5: Start sleeping 2 s...
[3.0007] execute
[4.0007] 3: DONE
[4.0009] 6: Start sleeping 3 s...
[4.0010] execute
[5.0012] 5: DONE
[5.0013] 7: Start sleeping 5 s...
[5.0014] execute
[7.0013] 4: DONE
[7.0013] 6: DONE
[7.0015] 8: Start sleeping 5 s...
[7.0015] execute
[7.0018] 9: Start sleeping 1 s...
[7.0018] execute
[8.0020] 9: DONE
[8.0022] 10: Start sleeping 4 s...
[10.0017] 7: DONE
[12.0025] 10: DONE
[12.0025] 8: DONE
© 2020 andrey-tech
Данный код распространяется на условиях лицензии MIT.