Вы неверно используете sleep() в php! Или как правильно готовить pcntl_fork()
Процессы создаются чрезвычайно просто для этого используется системный вызов fork, который создает точную копию исходного процесса, называемого родительским, а новый процесс называется дочерним.
В php эта функция называется pcntl_fork. И как же им пользоваться? Давайте разбираться.
Функция pcntl_fork() в случае успеха возвращает pid дочерного процесса в родительском потоке, а в дочернем будет 0. В случае сбоя, в родительском процессе будет возвращено -1
Эта программа не делает ничего полезного. Давайте изобразим тяжелую работу.
Ууупс. Наш мастер процесс завершился раньше чем дочерний и мы потеряли контроль над ним. Чтобы избежать этого воспользуемся функцией pcntl_waitpid, который может ждать завершения порожденного процесса или вернуть его статус
pcntl_waitpid приостанавливает выполнения мастера, пока дочерний процесс не завершится, но хотелось бы чтобы дочерний процесс сразу же вернул управление мастеру и он продолжил работать,
для этого третьм аргументом передадим WNOHANG. Второй параметр - $status, который передается по ссылке используется для получения дополнительной информации о статусе, подробнее в в мануале
Обернём это все в простенький класс
Теперь стало гораздо удобнее использовать:
Обработка сигналов
Что будет если мы пошлём мастер процессу SIGTERM?
Правильно, он завершиться, а чайлды продолжат работу. Поэтому нам нужно добавить свой обработчик сигналов.
Для этого используется функция pcntl_signal.
Добавилось два новых метода fork::signalHandler() и fork::kill(). Теперь мастер процесс при получении сигнала должен прибить своего чайда. И не забудьте включить асинхронную обработку сингалов pcntl_async_signals(true);.
Запускаем и пробуем.
Отлично! То что нам и нужно!
Заключение
Если у вас есть большая задача которую можно распараллелить, то смело используйте форки, правильно обрабатывайте сигналы и не забудьте включить их асинхронную обработку.
Как я и обещал в конце почему же вы не правильно используете sleep?
Как вы думаете, может ли проспать скрипт <100 секунд?
Неожиданно верно? На самом деле я послал 15 сигнал скрипту и sleep прервался вернув количество секунд которое он недоспал. Причём это описано в документации.
Так как лучше нам написать чтобы скрипт продолжил спать?