параллелизм в PHP
Я нахожусь в точке моего PHP-серверного API, где я делаю много запросов MySQL, и я хотел бы ускорить его, используя потоки mutliple, работающие с разными запросами, а затем возвращающие результаты.
Но как мне создать еще один поток в PHP? Я передаю почтовые параметры, поэтому простой shell_exec()
может работать, но кажется немного небезопасным. Варианты, которые я рассматриваю:
1) Сделайте запрос cURL, используя имеющиеся у меня параметры, обработайте JSON из запроса, а затем возврат
2) Вызовите shell_exec()
с помощью командной строки PHP и каким-то образом (как бы я это сделал??) обработайте ответ в PHP
Какие здесь лучшие варианты?
3 answers
В PHP нет поддержки потоковой передачи. Однако вы можете использовать pcntl
расширение для создания и управления вилками, но было бы лучше еще раз взглянуть на ваши алгоритмы, если вы пришли к выводу, что все должно быть сделано с потоковой передачей.
Одним из вариантов асинхронной обработки длительных операций было бы сохранение их в базе данных, а фоновый рабочий процесс извлекал бы их из базы данных, вычислял результаты, а затем сохранял результаты в база данных. Затем фронтальный скрипт будет искать их в базе данных, чтобы узнать, завершены ли они и каков результат.
Проверьте расширение pcntl. PHP вообще не поддерживает истинную потоковую обработку, поэтому вам придется реализовать псевдопотоки с помощью fork()ing. Обратите внимание, что процесс fork() намного "тяжелее", чем создание потока.
PHP не реализовал потоки (и, вероятно, никогда не будет реализован), потому что многие библиотеки PHP НЕ являются потокобезопасными. Это изменение pcntl
, которое обертывает функцию C fork
.
Я создал удобную оболочку для этих функций, которая позволяет мне управлять ими на более высоком уровне.
$thread1 = new Thread( function( $thread ) {
sleep( 4 );
$thread->write( "Hello\n" );
} );
$thread2 = new Thread( function( $thread ) {
sleep( 5 );
$thread->write( "World\n" );
} );
$thread3 = new Thread( function( $thread ) {
sleep( 6 );
} );
print $thread1->read(); // time: 0 -> 4
print $thread2->read(); // time: 4 -> 5
$thread3->join(); // time 5 -> 6
// More advanced handling:
// Thread::selectUntilJoin( array( $thread1, $thread2, $thread3 ), function () { ... }, function () { ... } );