аватар question@mail.ru · 01.01.1970 03:00

How to make a temporary cycle correctly?

We need to make a cycle that will perform a function for a minute with an interval of 1 sec.

What is the most effective way? I could not come up with anything better than this:

   from  time  impport  simn. seconds_left =  60    when  seconds_left & gt;  0 :  do_sometHing ()  seconds_left -=  1   Sleep (
                            
                            
                        
аватар answer@mail.ru · 01.01.1970 03:00

You can use range(n) to repeat something n times in Python:

for _ in="">in range(60):    do_someth_something()    time.sleep(1)

""Is this the right"" and ""effective"" is this the way? It depends on the specific task.

The code is simple and straightforward: call the do_something() function 60 times, each subsequent call occurs no earlier than one second after the previous call is completed. At the end, we wait a second before completing the loop.

Imagine do_something() takes half a second on average, then the loop will take a minute and a half or more. Whether this is a good thing depends on the task.

If you want calls to occur on the boundary of each second:

for _ in="">in range(60):    do_someth_something()    time.sleep(1 - time.time() % 1)

Accurate to the activity of other processes and threads (features of process schedulers/threads in the operating system, features of the GIL implementation of the selected version of the Python interpreter), every call to do_something() except the first one occurs close to the time when time.time() retus integer values.values.

For example, if time.time() retus X.3 seconds, then time.sleep() will sleep for at least 0.7 seconds (unless the signal handler throws an exception), which means that the next call to do_something() will occur at X + 1 seconds according to the system time (unless it jumped a lot while we were sleeping). In this case, the calls to do_something() can be more evenly distributed and the loop will end in almost exactly one minute according to time.time() (if the execution time of do_something() is less than a second). Whether this is a good thing depends on the task.

If you do not want to run do_something() if more than a minute has passed according to the selected timer, you can use an explicit condition:

deadline = time.monotonic() + 60while time.monotonic() < deadline:    do_something()    time.sleep(1)

e>

Things to take into account depending on the task:

  • What is the desired behavior if do_something()can be executed for more than a second: skip the iteration, run in a separate thread, thread/process pool?
  • What is the desired behavior if the system time jumps (because someone closed the laptop lid during a cycle or for any other reason happened, or the mobile OS shipped your process to save energy after some time, or the code inside the VM-big jumps are possible). Do you want to continue running the loop as if nothing happened when the system wakes up, or cancel subsequent calls (outdated), or complete the remaining calls as quickly as possible, without pause, or all at once (deadline passed)?

For example, if the time changes during execution, what do you think will happen? Is this behavior guaranteed by the module's sched documentation (will it change between different Python implementations/versions)? Is this important in your particular case? (I think the clarity of a simple loop with sleep() may become especially attractive at this point).

As a variation on the theme, you can either . In more complex cases, if you don't have any special preferences, you can. In some cases, it makes sense to use the system scheduler (for large intervals) such as cron and Windows Task Scheduler.

It is useful to know the reasons why call_repeatedly() the function was removed from :

Note: A previous version of this PEP defined a method named call_repeatedly() , which promised to call a callback at regular intervals. This has been withdrawn because the design of such a function is overspecified. On the one hand, a simple timer loop can easily be emulated using a callback that reschedules itself using call_later() ; it is also easy to write coroutine containing a loop and a sleep() call (a toplevel function in the module, see below). On the other hand, due to the complexities of accurate timekeeping there are many traps and pitfalls here for the unaware (), and different use cases require different behavior in edge cases. It is impossible to offer an API for this purpose that is bullet-proof in all cases, so it is deemed better to let application designers decide for themselves what kind of timer loop to implement.

Latest

Similar