Write this article I was led by a completely depressing, in my opinion, the situation with the solution of multitasking in PHP.
Most programmers claim that there is no multitasking in PHP, so do not even try, and the less blinkered still try to distort themselves by running a lot of scripts or, at best, they come up with some very private solutions for parallelizing downloads, for example.
The article is intended to demonstrate the idea of how to actually implement multitasking in virtually any programming language.
So say the proof of concept.
As they say, everything new is well forgotten old.
Although there is a complete implementation of this method, I will immediately warn you that I will not give a ready-made solution.
What exactly is the problem of organizing multitasking in most programming languages and in particular in PHP?
Consider a simple example:
')
It is required to write a function that waits for a certain time interval.
function wait($delta) { $time=microtime(1)+$delta; while($time <= microtime(1)) {} }
Everything is just like a rake, but a problem arises - this function will not return control until the specified time has elapsed.
Now, if we could get out of the cycle, and then return there again ...
In principle, it is possible to consider this function as a task, only the trouble is that two such tasks cannot be launched in parallel.
What is the difference between the wait function and the wait task? Essentially nothing.
Any task can be written as one function, but then what makes a function a task?
Right! The task is an algorithm for processing EVENTS. This is what actually makes function a task.
And what does the task do most of the time? Again, they guessed it - waiting for some kind of event. So you need to figure out how to wait without waiting.
What's the problem? Let's look at it a little differently.
In fact, any task can be represented as a finite state machine, and in this example, this machine has only 3 states.
That's what we would need.
function wait($delta) { switch($state) { case 'init': $time=microtime(1)+$delta; $state='wait'; break; case 'wait': if($time <= microtime(1)) { $state='exit'; } break; case 'exit':
With this description it is clear that the function will return its control immediately and will not wait for anything.
Suppose that the first time the function is called, it is always $ state = 'init';
If you regularly call this function, it will go through all its states, no matter how long
she practically didn’t take time in any state of time, because she makes a very small number of operations with each call.
It remains to solve the questions of how to initialize the $ state variable, how to save local variables between function calls, how to call this task, and how to stop its execution?
Let's start with the call.
let's get an array that will contain tasks for execution
$tasks=array();
Then the creation of the task will be reduced to adding the necessary data to this array.
For simplicity, we assume that the task will take only 1 parameter. In fact, this is enough, although not very convenient.
function startTask($name,$param) { global $tasks;
I want to note that by modifying $ tasks [$ id] ['name'] and $ tasks [$ id] ['param'], a task can
to force in the next cycle to perform another function instead of the current one. Those. the function will be different, but the task will remain the same.
Further development is possible towards more convenient functions for working with this mechanism.
For example, there is no limit on the number of parameters to be passed, a call to another task as a subtask of the current task, etc., but I will leave the implementation of these mechanisms to interested readers.
It all works just insanely fast.
And I want to note that all the above-written is not a ready-made solution, but a purely demonstration of the approach itself.
But its application opens up tremendous opportunities. For example, the use of multi_curl or sockets designed as tasks allows you to run multiple parallel download tasks, each of which can have its own result handlers and its own logic for working with data, besides other tasks at the same time can do other things.
You can write demons in PHP and even some hardware drivers.
For example, in one of the projects, the daemon served several devices on COM ports, each of which had its own data exchange protocol, was a TCP server for external clients, acted as a client for the central server and implemented all the logic of managing a payment terminal and at the same time occupied only 3% processor resources.
And all this was done by just one running script.
With multitasking, it all becomes very simple to implement.
There are cases when some kind of operation takes a lot (by the standards of the speed of other operations) time.
Then it is advisable to run them as external processes, but at the same time still making out their launch and monitoring their execution as tasks.
A demo showing the real work data of a similar example,
located here
http://tester.in/rt/task_test.php .