Немного предыстории:
Я строю серверное приложение на php, которое будет выполнять ряд независимых задач по запросу пользователя. Theres является жестким требованием к скорости для моего приложения, поэтому я хотел бы выполнять все эти задачи параллельно.
Я рассмотрел несколько решений (например, gearman, rabbitMQ, zeroMQ) и решил использовать zeroMQ (быстрый, хороший документ, гибкий и не требующий брокера). Это решает проблему связи / синхронизации между потоками для меня.
Вопрос:
Я хотел бы инициировать задачи только тогда, когда сервер получает запрос (чтобы не иметь длительный процесс). Поэтому я получаю запрос -> начать параллельное вычисление -> вернуть результат вычисления клиенту. Одним из решений для этого, кажется, pcntl_fork
Тем не менее документы упомянуть, что есть некоторые проблемы с его использованием в среде env производственного сервера, но на самом деле не указано, что это такое?
Мой другой вариант заключается в использовании proc_open
, но мне это нравится меньше, потому что это потребовало бы от меня сериализации входов каким-то образом, который кажется менее гибким и быстрым, чем разветвление. Есть ли у него какие-либо преимущества перед pcntl_fork
?
Есть ли другое решение (все еще используя php: p)?
Проходите осторожно, я вижу несколько красных флажков в вашем вопросе, которые наводят меня на мысль, что вы обеспокоены вещами, которые, возможно, вам не нужны, и, вероятно, вас не интересуют вещи, которыми вы должны быть.
Вы говорите, что предъявляете строгие требования к скорости — подтвердили ли вы, что обычный однопоточный PHP недостаточно быстр? Проведите какие-нибудь тесты, выясните ваши узкие места? Если ваши требования к скорости настолько велики, вы можете даже подумать об использовании другого языка, для всех прелестей PHP это никогда не будет самым эффективным молотком в наборе инструментов. Java — хороший вариант для полной скорости, а node.js — хороший вариант, если ваши узкие места зависят от ввода-вывода. Моя главная проблема заключается в том, что в отсутствие дополнительной информации этот вопрос пахнет преждевременная оптимизация. Это может быть несправедливо, и вы, возможно, пропустили эти детали, потому что это не было суть вашего вопроса, но, как посторонний человек, я по крайней мере хотел убедиться, что вы думаете об этих вещах, если вы еще этого не сделали.
Вы хотите избежать длительных процессов — почему? В длительных процессах нет ничего плохого, но это Чувствовать неправильно, когда то, к чему вы привыкли, это псевдоэффективная природа Apache + mod_php «по требованию». Убедитесь, что вы не пытаетесь избежать чего-то только потому, что вы к этому не привыкли.
Похоже, вы описываете параллельную обработку внутри вашего PHP-приложения — как и любая другая веб-страница, которую вы пишете, Apache запускает ваш PHP-сценарий, который запускает другой процесс и, вместо того, чтобы выполнять его действия последовательно, выполняет их в Параллельно, завершает и возвращает пользователю по завершении рендеринга страницы. Если это правильно, то вот ответ на ваш оригинальный вопрос:
Вы не можете использовать pcntl_fork
из веб-процесса, только из командной строки. Подробности этого на странице, на которую вы ссылаетесь, внизу в комментариях:
Это не вопрос «не должен», это «не может». Хотя я скомпилировал в PCNTL с помощью —enable-pcntl, оказалось, что он компилируется только в CLI-версию PHP, а не в модуль Apache. […] function_exists (‘pcntl_fork’) возвращал false, даже если он скомпилирован правильно. Оказывается, он возвращает истину просто отлично из CLI, и возвращает только ложь для HTTP-запросов. То же самое верно для ВСЕХ функций pcntl _ * ().
… Это означает, что либо вам придется инициировать процесс разветвления как отдельный длительный процесс, либо вам придется запускать его по требованию с proc_open
нет способа заставить его работать так, как я предполагаю, что вы этого хотите.
Других решений пока нет …