Как сделать задержку в python
Перейти к содержимому

Как сделать задержку в python

  • автор:

How to implement a Timeout functionality in Python

Omar H.

A very common question that keeps coming up on Quora and Stack Overflow is, how to set a timeout on some function call or a thread in Python.

I wanted to sum up multiple approaches to implement such feature in one concrete article, where all suggested solutions are platform(etc.. UNIX/LINUX, Windows) independent.

Python sleep(): How to Add Time Delays to Your Code

Have you ever needed to make your Python program wait for something? Most of the time, you’d want your code to execute as quickly as possible. But there are times when letting your code sleep for a while is actually in your best interest.

For example, you might use a Python sleep() call to simulate a delay in your program. Perhaps you need to wait for a file to upload or download, or for a graphic to load or be drawn to the screen. You might even need to pause between calls to a web API, or between queries to a database. Adding Python sleep() calls to your program can help in each of these cases, and many more!

In this tutorial, you’ll learn how to add Python sleep() calls with:

  • time.sleep()
  • Decorators
  • Threads
  • Async IO
  • Graphical User Interfaces

This article is intended for intermediate developers who are looking to grow their knowledge of Python. If that sounds like you, then let’s get started!

Free Bonus: Get our free «The Power of Python Decorators» guide that shows you three advanced decorator patterns and techniques you can use to write to cleaner and more Pythonic programs.

Adding a Python sleep() Call With time.sleep()

Python has built-in support for putting your program to sleep. The time module has a function sleep() that you can use to suspend execution of the calling thread for however many seconds you specify.

Here’s an example of how to use time.sleep() :

If you run this code in your console, then you should experience a delay before you can enter a new statement in the REPL.

Note: In Python 3.5, the core developers changed the behavior of time.sleep() slightly. The new Python sleep() system call will last at least the number of seconds you’ve specified, even if the sleep is interrupted by a signal. This does not apply if the signal itself raises an exception, however.

You can test how long the sleep lasts by using Python’s timeit module:

Here, you run the timeit module with the -n parameter, which tells timeit how many times to run the statement that follows. You can see that timeit ran the statement 3 times and that the best run time was 3 seconds, which is what was expected.

The default number of times that timeit will run your code is one million. If you were to run the above code with the default -n , then at 3 seconds per iteration, your terminal would hang for approximately 34 days! The timeit module has several other command line options that you can check out in its documentation.

Let’s create something a bit more realistic. A system administrator needs to know when one of their websites goes down. You want to be able to check the website’s status code regularly, but you can’t query the web server constantly or it will affect performance. One way to do this check is to use a Python sleep() system call:

Here you create uptime_bot() , which takes a URL as its argument. The function then attempts to open that URL with urllib . If there’s an HTTPError or URLError , then the program catches it and prints out the error. (In a live environment, you would log the error and probably send out an email to the webmaster or system administrator.)

If no errors occur, then your code prints out that all is well. Regardless of what happens, your program will sleep for 60 seconds. This means that you only access the website once every minute. The URL used in this example is bad, so it will output the following to your console once every minute:

Go ahead and update the code to use a known good URL, like http://www.google.com . Then you can re-run it to see it work successfully. You can also try to update the code to send an email or log the errors. For more information on how to do this, check out Sending Emails With Python and Logging in Python.

Adding a Python sleep() Call With Decorators

There are times when you need to retry a function that has failed. One popular use case for this is when you need to retry a file download because the server was busy. You usually won’t want to make a request to the server too often, so adding a Python sleep() call between each request is desirable.

Another use case that I’ve personally experienced is where I need to check the state of a user interface during an automated test. The user interface might load faster or slower than usual, depending on the computer I’m running the test on. This can change what’s on the screen at the moment my program is verifying something.

In this case, I can tell the program to sleep for a moment and then recheck things a second or two later. This can mean the difference between a passing and failing test.

You can use a decorator to add a Python sleep() system call in either of these cases. If you’re not familiar with decorators, or if you’d like to brush up on them, then check out Primer on Python Decorators. Let’s look at an example:

sleep() is your decorator. It accepts a timeout value and the number of times it should retry , which defaults to 3. Inside sleep() is another function, the_real_decorator() , which accepts the decorated function.

Finally, the innermost function wrapper() accepts the arguments and keyword arguments that you pass to the decorated function. This is where the magic happens! You use a while loop to retry calling the function. If there’s an exception, then you call time.sleep() , increment the retries counter, and try running the function again.

Now rewrite uptime_bot() to use your new decorator:

Here, you decorate uptime_bot() with a sleep() of 3 seconds. You’ve also removed the original while loop, as well as the old call to sleep(60) . The decorator now takes care of this.

One other change you’ve made is to add a raise inside of the exception handling blocks. This is so that the decorator will work properly. You could write the decorator to handle these errors, but since these exceptions only apply to urllib , you might be better off keeping the decorator the way it is. That way, it will work with a wider variety of functions.

Note: If you’d like to brush up on exception handling in Python, then check out Python Exceptions: An Introduction.

There are a few improvements that you could make to your decorator. If it runs out of retries and still fails, then you could have it re-raise the last error. The decorator will also wait 3 seconds after the last failure, which might be something you don’t want to happen. Feel free to try these out as an exercise!

Adding a Python sleep() Call With Threads

There are also times when you might want to add a Python sleep() call to a thread. Perhaps you’re running a migration script against a database with millions of records in production. You don’t want to cause any downtime, but you also don’t want to wait longer than necessary to finish the migration, so you decide to use threads.

Note: Threads are a method of doing concurrency in Python. You can run multiple threads at once to increase your application’s throughput. If you’re not familiar with threads in Python, then check out An Intro to Threading in Python.

To prevent customers from noticing any kind of slowdown, each thread needs to run for a short period and then sleep. There are two ways to do this:

  1. Use time.sleep() as before.
  2. Use Event.wait() from the threading module.

Let’s start by looking at time.sleep() .

Using time.sleep()

The Python Logging Cookbook shows a nice example that uses time.sleep() . Python’s logging module is thread-safe, so it’s a bit more useful than print() statements for this exercise. The following code is based on this example:

Here, you use Python’s threading module to create two threads. You also create a logging object that will log the threadName to stdout. Next, you start both threads and initiate a loop to log from the main thread every so often. You use KeyboardInterrupt to catch the user pressing Ctrl + C .

Try running the code above in your terminal. You should see output similar to the following:

As each thread runs and then sleeps, the logging output is printed to the console. Now that you’ve tried an example, you’ll be able to use these concepts in your own code.

Using Event.wait()

The threading module provides an Event() that you can use like time.sleep() . However, Event() has the added benefit of being more responsive. The reason for this is that when the event is set, the program will break out of the loop immediately. With time.sleep() , your code will need to wait for the Python sleep() call to finish before the thread can exit.

The reason you’d want to use wait() here is because wait() is non-blocking, whereas time.sleep() is blocking. What this means is that when you use time.sleep() , you’ll block the main thread from continuing to run while it waits for the sleep() call to end. wait() solves this problem. You can read more about how all this works in Python’s threading documentation.

Here’s how you add a Python sleep() call with Event.wait() :

In this example, you create threading.Event() and pass it to worker() . (Recall that in the previous example, you instead passed a dictionary.) Next, you set up your loops to check whether or not event is set. If it’s not, then your code prints a message and waits a bit before checking again. To set the event, you can press Ctrl + C . Once the event is set, worker() will return and the loop will break, ending the program.

Note: If you’d like to learn more about dictionaries, then check out Dictionaries in Python.

Take a closer look at the code block above. How would you pass in a different sleep time to each worker thread? Can you figure it out? Feel free to tackle this exercise on your own!

Adding a Python sleep() Call With Async IO

Asynchronous capabilities were added to Python in the 3.4 release, and this feature set has been aggressively expanding ever since. Asynchronous programming is a type of parallel programming that allows you to run multiple tasks at once. When a task finishes, it will notify the main thread.

asyncio is a module that lets you add a Python sleep() call asynchronously. If you’re unfamiliar with Python’s implementation of asynchronous programming, then check out Async IO in Python: A Complete Walkthrough and Python Concurrency & Parallel Programming.

Here’s an example from Python’s own documentation:

In this example, you run main() and have it sleep for one second between two print() calls.

Here’s a more compelling example from the Coroutines and Tasks portion of the asyncio documentation:

In this code, you create a worker called output() that takes in the number of seconds to sleep and the text to print out. Then, you use Python’s await keyword to wait for the output() code to run. await is required here because output() has been marked as an async function, so you can’t call it like you would a normal function.

When you run this code, your program will execute await 3 times. The code will wait for 1, 2, and 3 seconds, for a total wait time of 6 seconds. You can also rewrite the code so that the tasks run in parallel:

Now you’re using the concept of tasks, which you can make with create_task() . When you use tasks in asyncio , Python will run the tasks asynchronously. So, when you run the code above, it should finish in 3 seconds total instead of 6.

Adding a Python sleep() Call With GUIs

Command-line applications aren’t the only place where you might need to add Python sleep() calls. When you create a Graphical User Interface (GUI), you’ll occasionally need to add delays. For example, you might create an FTP application to download millions of files, but you need to add a sleep() call between batches so you don’t bog down the server.

GUI code will run all its processing and drawing in a main thread called the event loop. If you use time.sleep() inside of GUI code, then you’ll block its event loop. From the user’s perspective, the application could appear to freeze. The user won’t be able to interact with your application while it’s sleeping with this method. (On Windows, you might even get an alert about how your application is now unresponsive.)

Fortunately, there are other methods you can use besides time.sleep() . In the next few sections, you’ll learn how to add Python sleep() calls in both Tkinter and wxPython.

Sleeping in Tkinter

tkinter is a part of the Python standard library. It may not be available to you if you’re using a pre-installed version of Python on Linux or Mac. If you get an ImportError , then you’ll need to look into how to add it to your system. But if you install Python yourself, then tkinter should already be available.

You’ll start by looking at an example that uses time.sleep() . Run this code to see what happens when you add a Python sleep() call the wrong way:

Once you’ve run the code, press the button in your GUI. The button will stick down for three seconds as it waits for sleep() to finish. If the application had other buttons, then you wouldn’t be able to click them. You can’t close the application while it’s sleeping, either, since it can’t respond to the close event.

To get tkinter to sleep properly, you’ll need to use after() :

Here you create an application that is 400 pixels wide by 400 pixels tall. It has no widgets on it. All it will do is show a frame. Then, you call self.root.after() where self.root is a reference to the Tk() object. after() takes two arguments:

  1. The number of milliseconds to sleep
  2. The method to call when the sleep is finished

In this case, your application will print a string to stdout after 3 seconds. You can think of after() as the tkinter version of time.sleep() , but it also adds the ability to call a function after the sleep has finished.

You could use this functionality to improve user experience. By adding a Python sleep() call, you can make the application appear to load faster and then start some longer-running process after it’s up. That way, the user won’t have to wait for the application to open.

Sleeping in wxPython

There are two major differences between wxPython and Tkinter:

  1. wxPython has many more widgets.
  2. wxPython aims to look and feel native on all platforms.

The wxPython framework is not included with Python, so you’ll need to install it yourself. If you’re not familiar with wxPython, then check out How to Build a Python GUI Application With wxPython.

In wxPython, you can use wx.CallLater() to add a Python sleep() call:

Here, you subclass wx.Frame directly and then call wx.CallLater() . This function takes the same parameters as Tkinter’s after() :

  1. The number of milliseconds to sleep
  2. The method to call when the sleep is finished

When you run this code, you should see a small blank window appear without any widgets. After 4 seconds, you’ll see the string ‘I was delayed’ printed to stdout.

One of the benefits of using wx.CallLater() is that it’s thread-safe. You can use this method from within a thread to call a function that’s in the main wxPython application.

Conclusion

With this tutorial, you’ve gained a valuable new technique to add to your Python toolbox! You know how to add delays to pace your applications and prevent them from using up system resources. You can even use Python sleep() calls to help your GUI code redraw more effectively. This will make the user experience much better for your customers!

To recap, you’ve learned how to add Python sleep() calls with the following tools:

  • time.sleep()
  • Decorators
  • Threads
  • asyncio
  • Tkinter
  • wxPython

Now you can take what you’ve learned and start putting your code to sleep!

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Using sleep() to Code a Python Uptime Bot

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Mike Driscoll

Mike has been programming in Python for over a decade and loves writing about Python!

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Aldren Santos

Geir Arne Hjelle

Jaya Zhané

Jon Fincher

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

What Do You Think?

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal. Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Python sleep(): Как выполнить код с задержкой?

sleep в Python

Знакома ли вам ситуация, когда программа Python должна выполняться не сразу? В большинстве случаев требуется, чтобы код запускался как можно скорее. Однако порой перед работой оптимальнее будет дать программе немного поспать.

Содержание статьи

В Python есть возможность вызвать функцию sleep() для симуляции задержки в выполнении программы. Быть может, вам нужно дождаться загрузки, скачивания или появления графического объекта на экране. Также может потребоваться сделать паузу между вызовами к веб API или запросами к базе данных. В таких случаях поможет добавление вызова функции sleep() в программу.

Главные аспекты данного руководства по вызову sleep() в Python:

  • time.sleep() ; ; ; ;
  • Графический пользовательский интерфейс GUI.

Данная статья предназначена для разработчиков Python среднего уровня, что стремятся повысить свою квалификацию. Если это похоже на вас, приступим!

Вызов sleep() через time.sleep()

В Python есть встроенная поддержка для погружения программы в сон. У модуля time есть функция sleep(), что позволяет отсрочить выполнение вызываемого потока на указанное количество секунд.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Далее дан пример использования time.sleep() :

При запуске кода из консоли, задержку нужно проводить перед вводом нового оператора в REPL.

На заметку: В Python 3.5 разработчики слегка изменили поведение time.sleep() . Благодаря новой системе вызова sleep() эффект отсрочки будет длиться как минимум на продолжении указанного количества секунд, даже в том случае, если сон прерывается сигналом. Однако, это не касается случаев, если сигнал является признаком вызова исключения.

Вы можете протестировать, как долго продлиться сон с помощью модуля Python timeit:

Здесь модуль timeit запускается с параметром -n , что указывает timeit , сколько раз выполнять последующий оператор. Можно заметить, что timeit выполнил оператор 3 раза, а лучшее время длилось 3 секунды, чего и следовало ожидать.

По умолчанию timeit будет запускать код миллион раз. Если бы вы запустили вышеуказанный код, оставив значение -n по умолчанию, тогда при 3 секундах на итерацию код завис бы примерно на 34 дня! У модуля timeit есть несколько других настроек для командной строки, с которыми можно ознакомиться в документации.

Создадим что-то более практичное. Системному администратору всегда нужно быть в курсе, если какой-то из сайтов упал. Вы бы хотели иметь возможность проверить код состояния сайта регулярно, но запрашивать веб сервер постоянно нельзя, ведь это сильно повлияет на производительность. В Python одним из простых способов совершить такую проверку является использование системного вызова sleep() :

Здесь создается uptime_bot() , что принимает URL в качестве аргумента. Затем функция пытается открыть данный URL c urllib . При возникновении HTTPError или URLError программа перехватывает ошибку и выводит на экран. На практике вам, скорее всего, придется зафиксировать ошибку и отправить письмо веб-мастеру или системному администратору.

Если ошибок нет, код спокойно выполняется. Вне зависимости от того, что произойдет, программа уходит в сон на 60 секунд. Это значит, что доступ к сайту будет раз за минуту. URL, используемый в примере, содержит ошибки. Ежеминутный вывод на консоли выглядит следующим образом:

Попробуйте обновить код, используя проверенный хороший URL, к примеру https://www.google.com/. После этого вы можете перезапустить программу и проверить, что изменилось. Также можно попробовать обновить код для отправки сообщения или записи об ошибке. Для получения более подробной информации можете ознакомиться со статьями отправка писем smtp и логирование.

Вызов sleep() с декораторами

В некоторых случаях нужно повторно запустить неудачно выполненную в первый раз функцию. Зачастую это происходит, когда требуется повторить загрузку файла ввиду ранней перегрузки сервера. Как правило, никто не хочет делать частые запросы на серверы, поэтому добавление в Python вызова sleep() между каждым запросом предпочтительно.

Другим возможным случаем использования sleep() является необходимость проверки состояния пользовательского интерфейса во время автоматического теста. В зависимости от компьютера, на котором запускается тест, пользовательский интерфейс может грузиться быстрее или медленнее обычного. Это может изменить отображаемое на экране во время проверки программой чего-то.

В данном случае можно указать программе, чтобы та погрузилась в сон на мгновенье и затем проверить все опять через несколько секунд. Это может означать разницу между прохождением или провалом теста.

Для добавления системного вызова sleep() в Python можно использовать декоратор в каждом из данных случаев. Разберем следующий пример:

sleep() является вашим декоратором. Он принимает значение timeout и количество раз для повтора retry , что по умолчанию равняется 3. Внутри sleep() есть другая функция, the_real_decorator() , которая принимает декорируемую функцию.

В конечном итоге самая внутренняя функция wrapper() принимает аргументы и ключевые слова, которые вы передаете декорируемой функции. Здесь все и происходит! Используется цикл while, чтобы повторить вызов функции. Если возникла ошибка, вызывается time.sleep() , увеличивается счетчик попыток retries и повторяется попытка запуска функции.

Теперь переписывается uptime_bot() для использования нового декоратора:

Здесь вы декорируете uptime_bot() с помощью sleep() в 3 секунды. Вы также удалили оригинальный цикл while и старый вызов sleep(60) . Декоратор теперь позаботится об этом.

Другое изменение состоит в добавлении raise внутри блоков, отвечающих за обработку исключений. Это нужно для правильной работы декоратора. Можно также написать декоратор, чтобы он отвечал за ошибки, однако ввиду того, что исключения касаются только urllib , может быть лучше сохранить декоратор в текущем состоянии. В таком случае он будет работать c более широким ассортиментом функций.

На заметку: При желании более подробно узнать о том, как справляться с исключениями в Python, можете ознакомиться со статьей: Обработка исключений в Python

Декоратору можно добавить несколько улучшений. Если число попыток заканчивается, и он по-прежнему проваливается, тогда можно сделать так, чтобы он повторно вызвал последнюю ошибку. Декоратор подождет 3 секунды после последней неудачи, что не всегда нужно. Можете попробовать поэкспериментировать самостоятельно.

Вызов sleep() в потоках

Могут возникнуть ситуации, когда в Python требуется добавить вызов sleep() для потока. К примеру, запуск скрипта миграции для базы данных с миллионами записей. Здесь важно избежать простоя, а также не ждать дольше необходимого для завершения миграции, поэтому можно использовать потоки.

На заметку: Потоки являются одним из методов использования конкурентности в Python. Можно запустить несколько потоков одновременно, чтобы увеличить производительность приложения. Если потоки в Python являются для вас новой темой, ознакомьтесь со статьей модуль threading.

Чтобы клиенты не замечали какого-либо замедления, каждый поток должен работать в течение короткого периода времени, а затем уходить в сон. Есть два способа сделать это:

Rukovodstvo

статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.

Python: сделать временную задержку (спящий режим) для выполнения кода

Введение Задержка кода (также известная как «спящий») — это именно то, что подразумевает название, задержка выполнения кода на некоторое время. Наиболее частая потребность в отложении кода — это когда мы ждем завершения какого-либо другого процесса, чтобы мы могли работать с результатом этого процесса. В многопоточных системах потоку может потребоваться дождаться, пока другой поток закончит операцию, чтобы продолжить работу с этим результатом. Другой пример — уменьшение нагрузки на сервер, над которым мы работаем.

Время чтения: 8 мин.

Вступление

Задержка кода (также известная как « спящий» ) — это именно то, что подразумевает название, задержка выполнения кода на некоторое время. Наиболее частая потребность в отложении кода — это когда мы ждем завершения какого-либо другого процесса, чтобы мы могли работать с результатом этого процесса. В многопоточных системах потоку может потребоваться дождаться, пока другой поток закончит операцию, чтобы продолжить работу с этим результатом.

Другой пример — снижение нагрузки на сервер, с которым мы работаем. Например, при парсинге веб-страниц (этически) и соблюдении ToS рассматриваемого веб-сайта с соблюдением robots.txt — вы вполне можете отложить выполнение каждого запроса, чтобы не перегружать ресурсы сервера.

Многие запросы, отправляемые в быстрой последовательности, могут, в зависимости от рассматриваемого сервера, быстро задействовать все свободные соединения и фактически превратиться в DoS-атаку . Чтобы дать передышку, а также чтобы убедиться, что мы не оказываем негативного воздействия ни на пользователей веб-сайта, ни на сам веб-сайт — мы ограничили количество отправляемых запросов, задерживая каждый из них.

Студент, ожидающий результатов экзамена, может яростно обновлять сайт своей школы в ожидании новостей. В качестве альтернативы они могут написать сценарий, который проверяет, есть ли на веб-сайте что-нибудь новое. В некотором смысле, задержка кода технически может стать планированием кода с допустимым циклом и условием завершения — при условии, что действующий механизм задержки не блокирует .

В этой статье мы рассмотрим, как отложить выполнение кода в Python — также известное как спящий режим . Это можно сделать несколькими способами:

Код задержки с time.sleep ()

Одним из наиболее распространенных решений проблемы является функция sleep() встроенного модуля time Он принимает количество секунд, в течение которых процесс должен засыпать — в отличие от многих других языков, которые основаны на миллисекундах :

Совершенно ясно, что мы можем видеть задержку в 5 секунд между двумя print() с довольно высокой точностью — вплоть до второго десятичного знака. Если вы хотите спать менее 1 секунды, вы также можете легко передать нецелые числа:

Однако имейте в виду, что с двумя десятичными знаками продолжительность сна может быть не совсем точной , особенно из-за того, что ее трудно проверить, учитывая тот факт, что print() требуют некоторого (переменного) времени для выполнения.

time.sleep() есть один серьезный недостаток, очень заметный в многопоточных средах.

Он захватывает поток, в котором находится, и блокирует его на время сна . Это делает его непригодным для более длительного ожидания, так как в течение этого периода он забивает поток процессора. Кроме того, это делает его непригодным для асинхронных и реактивных приложений , которым часто требуются данные и обратная связь в реальном времени.

Еще одно замечание о time.sleep() — это то, что вы не можете его остановить. После запуска вы не можете отменить его извне, не завершив всю программу или sleep() генерировать исключение, которое остановило бы его.

Асинхронное и реактивное программирование

Асинхронное программирование вращается вокруг параллельного выполнения, когда задача может выполняться и завершаться независимо от основного потока.

В синхронном программировании — если функция A вызывает функцию B , она останавливает выполнение до тех пор, пока функция B не завершит выполнение, после чего функция A может возобновиться.

В асинхронном программировании — если функция A вызывает функцию B , независимо от ее зависимости результата от функции B , обе могут выполняться одновременно, и, если необходимо, дождаться завершения другой, чтобы использовать результаты друг друга.

Реактивное программирование — это подмножество асинхронного программирования , которое запускает выполнение кода реактивно , когда данные представлены, независимо от того, занята ли функция, которая должна их обрабатывать. Реактивное программирование в значительной степени опирается на архитектуры, управляемые сообщениями (где сообщение обычно является событием или командой ).

И асинхронные, и реактивные приложения сильно страдают от блокировки кода, поэтому использование чего-то вроде time.sleep() для них не подходит. Давайте посмотрим на некоторые варианты задержки неблокирующего кода.

Код задержки с asyncio.sleep ()

Asyncio — это библиотека Python, предназначенная для написания параллельного кода и использующая async / await , который может быть знаком разработчикам, которые использовали его на других языках.

Установим модуль через pip :

После установки мы можем import его в наш скрипт и переписать нашу функцию:

При работе с asyncio мы помечаем функции, которые выполняются асинхронно, как async , и await результатов таких операций, как asyncio.sleep() которые будут завершены в какой-то момент в будущем.

Как и в предыдущем примере, это будет напечатано два раза с интервалом в 5 секунд:

Хотя на самом деле это не иллюстрирует преимущества использования asyncio.sleep() . Давайте перепишем пример для параллельного выполнения нескольких задач, где это различие гораздо более ясно:

Здесь у нас есть async функция, которая имитирует трудоемкую задачу, выполнение которой занимает 5 секунд. Затем, используя asyncio , мы создаем несколько задач . Однако каждая задача может выполняться асинхронно, только если мы вызываем их асинхронно. Если бы мы запускали их последовательно, они также выполнялись бы последовательно.

Для их параллельного вызова мы используем gather() , которая собирает задачи и выполняет их:

Все они выполняются одновременно, и время ожидания для трех из них не 15 секунд, а 5.

С другой стороны, если бы мы настроили этот код, чтобы вместо time.sleep()

Мы будем ждать 5 секунд между каждым оператором print()

Код задержки с таймером

Класс Timer — это Thread , который может запускать и выполнять операции только по прошествии определенного периода времени. Это именно то, что мы ищем, хотя использование Thread s для задержки кода является излишним, если вы еще не работаете с многопоточной системой.

Класс Timer должен быть start() , и его можно остановить с помощью cancel() . Его конструктор принимает целое число, обозначающее количество секунд ожидания перед выполнением второго параметра — функции.

Создадим функцию и выполним ее через Timer :

Метод cancel() очень удобен, если у нас работает несколько функций, и мы хотели бы отменить выполнение функции на основе результатов другой или другого условия.

Напишем функцию f() , которая вызывает как f2() и f3() . f2() вызывается как есть — и возвращает случайное целое число от 1 до 10, имитируя время, необходимое для запуска этой функции.

f3() вызывается через Timer и если результат f2() больше 5 , f3() отменяется, тогда как если f2() выполняется в «ожидаемое» время меньше 5 — f3() запускается после таймер заканчивается:

Выполнение этого кода несколько раз будет выглядеть примерно так:

Код задержки с событием

Класс Event можно использовать для генерации событий. Одно событие может быть "прослушано" несколькими потоками. Функция Event.wait() блокирует поток, в котором она находится, за исключением Event.isSet() . После того, как вы set() событие, все ожидающие потоки пробуждаются, и Event.wait() становится неблокирующим .

Это можно использовать для синхронизации потоков — все они накапливаются и wait() пока не будет установлено определенное событие, после чего они могут определять свой поток.

Давайте создадим waiter и запустим его несколько раз в разных потоках. Каждый официант начинает работать в определенное время и каждую секунду проверяет, работают ли они еще час, прямо перед тем, как принять заказ, на выполнение которого уходит секунда. Они будут работать, пока не будет назначено Событие, а точнее, их рабочее время не истечет.

У каждого официанта будет свой собственный поток, в то время как управление находится в основном потоке и звонит, когда каждый может позвонить домой. Поскольку сегодня они чувствуют себя очень щедрыми, они сократят рабочее время и отпустят официантов домой через 4 секунды работы:

Выполнение этого кода приводит к:

end_of_work здесь использовалось для синхронизации двух потоков и управления, когда они работают, а когда нет, задерживая выполнение кода на установленное время между проверками.

Заключение

В этом руководстве мы рассмотрели несколько способов задержки выполнения кода в Python, каждый из которых применим к разному контексту и требованиям.

time.sleep() очень полезен для большинства приложений, хотя он не совсем оптимален для длительного времени ожидания, обычно не используется для простого планирования и блокирует.

Используя asyncio , у нас есть асинхронная версия time.sleep() которую мы можем await .

Класс Timer задерживает выполнение кода и при необходимости может быть отменен.

Класс Event генерирует события, которые несколько потоков могут прослушивать и соответственно реагировать, задерживая выполнение кода до тех пор, пока не будет установлено определенное событие.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *