E
E
Ernest Faizullin2016-03-03 22:06:45
PHP
Ernest Faizullin, 2016-03-03 22:06:45

Loop with a timeout of exactly 1 second?

Hi all.
The essence of the question - how can you ensure that each iteration of the loop lasts exactly 1 second? Purpose: to synchronize the execution of a function (let's say check_storage), with real time up to a second, to monitor data (for example, from redis) for changes. In short, it is mandatory to perform a check every second, because some changes to the store are initiated from the outside.
How I try. By cron every minute: in a loop from 1 to 60, I execute my check_storage and after each iteration I cause a sleep pause of 1 second:
*/1 * * * * php /var/www/test/timer.php

for ($i = 1; $i <= 60; $i++)  {
    check_storage(); // выполняется примерно 0.03 секунды
    sleep(1); // пауза 1 секунда
}

but check_storage also takes some time and the total pause at each iteration lasts 1 second + check_storage execution time, it turns out that each cycle continues for 2 more iterations at the time when a new minute with a new cycle has started.
It is necessary to somehow fit 60 iterations in one minute or find another way. I am sure that there are some time-tested methods for this, but I have not come across this yet and therefore I ask experts to help come to the right solution. Thanks in advance for any help!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
pi314, 2016-03-03
@erniesto77

Your question can be cited as a visual aid on the topic "How exactly does the crooked architecture of the system climb sideways" :) The main problem is that the integration of components through storage is evil, sooner or later (more often sooner) forcing the developer to perform a handstand. So, if there is such an opportunity, try to eliminate the evil at the root, i.e. find a way to learn about the changes, well, or at least about the fact itself, before, not after. Then you don't have to poll anything in the loop, but only react to changes. And that's half the problem!
If there is no way, but you still need to do it, first accept the fact that you will never achieve exactly 86400 calls per day every second in PHP, unless you put a real-time kernel / write the corresponding code in C, etc. etc. Especially if storage is running on the same processor in the same OS, and the amount of data in it will increase over time. But this is almost certainly not necessary, but you need to analyze the task and understand what is actually critical and what deviations from the ideal are possible without compromising functionality.
"Approximately 0.03s" in itself does not mean anything. Is it always or if there are no changes, or if they are of a small volume? And if 90% of the data is updated? This is one. Two: if changes are detected, how long can they take to process (in the worst case)? .. And finally, three: if the "next second" has already arrived, and we still have not finished processing past changes, a number of questions arise. Does it even make sense in this case to check for new changes (can we process them meaningfully if we find them)? If so, at least 2 threads will be needed. If not, how critical is it to miss that second? And how much more can you skip without sacrificing functionality? Suppose this is not critical, and we have already missed a second (or several), which is more important for us: so that the next check is performed as close as possible to the border "
Without knowing the answers to these and similar questions, it is impossible to offer a "correct" solution. But as a spherical horse in a vacuum, we can advise an infinite loop in which a check is performed, a reaction to the changes found, after which the time until the next check is calculated, for which sleep () is performed.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question