If you need a separate process for each task handler, you can consider using five separate processes. The first is the listener and processes the new incoming tasks and puts it in the queue. Each task handler initially sends a job request, and also when it completes the processing of the task. When the listener receives this request, it executes the next task in the queue for the task handler or puts the task handler in the handler queue if the task queue is empty. When the task queue moves from empty to non-empty, it checks to see if there is a ready-made task handler in the handler queue. If so, then this task handler exits the queue and delivers the task from the task queue to the task handler.
The PHP process has set tasks for the listener, while task handlers will receive tasks from the listener. The listener simply waits for sending or receiving requests and processes them. You can think of the listener as a simple web server, but each socket connection to the PHP process and each task handler can be permanent.
Since the number of sockets is small and constant, any of the multiplexing calls may work ( select , poll , epoll , kqueue or something the best and / or available for your system), but it may be easiest to use a separate thread to process each socket synchronously . Then the finished task handler queue will be a semaphore or condition variable in the task queue. In a thread that handles interference from the PHP process, tasks will be placed in the task queue and up the semaphore. Each thread that processes ready-made tasks will reset the semaphore, and then distract the task from the task queue. The task queue itself may need mutual exclusive protection, depending on how it is implemented.
source share