Python: Pass или Sleep для длительных процессов?
Я пишу приложение обработки очереди, которое использует потоки для ожидания и ответа на сообщения очереди, которые должны быть доставлены в приложение. Для основной части приложения она просто должна оставаться активной. Пример кода, например:
while True:
pass
или
while True:
time.sleep(1)
Какой из них будет иметь наименьшее влияние на систему? Какой предпочтительный способ ничего не делать, но сохранить приложение python?
Ответы
Ответ 1
Я бы предположил, что time.sleep() будет иметь меньше накладных расходов на систему. Использование pass приведет к тому, что цикл немедленно переоценит и привяжет CPU, тогда как использование time.sleep позволит временно приостановить выполнение.
EDIT: просто чтобы доказать точку, если вы запустите интерпретатор python и запустите это:
>>> while True:
... pass
...
Вы можете посмотреть, как Python начнет потреблять 90-100% процессор мгновенно, по сравнению с:
>>> import time
>>> while True:
... time.sleep(1)
...
который почти не регистрируется на мониторе активности (здесь используется OS X, но для каждой платформы он должен быть одинаковым).
Ответ 2
Зачем спать? Вы не хотите спать, вы хотите дождаться окончания потоков.
Итак,
# store the threads you start in a your_threads list, then
for a_thread in your_threads:
a_thread.join()
Смотрите: thread.join
Ответ 3
Вы не придаете большого значения тому, что вы на самом деле делаете, но, возможно, Queue
можно использовать вместо явной занятости -wait loop? Если нет, я бы предположил, что sleep
будет предпочтительнее, так как я считаю, что он будет потреблять меньше CPU (как уже отмечали другие).
[Отредактировано в соответствии с дополнительной информацией в комментарии ниже.]
Возможно, это очевидно, но в любом случае то, что вы могли бы сделать в случае, когда вы читаете информацию из блокирующих сокетов, состоит в том, чтобы один поток читался из сокета и отправлял соответствующим образом отформатированные сообщения в Queue
, а затем остальная часть ваших "рабочих" потоков, просматриваемых из этой очереди; рабочие затем блокируются при чтении из очереди без необходимости ни pass
, ни sleep
.
Ответ 4
Я всегда видел/слышал, что использование сна - лучший способ сделать это. Использование сна будет заставлять ваше использование процессора интерпретатора Python отходить.
Ответ 5
Если вы ищете короткий метод zero-cpu для непрерывного цикла до KeyboardInterrupt, вы можете использовать:
from threading import Event
Event().wait()
Примечание. Из- за ошибки это работает только на Python 3. 2+. Кроме того, похоже, что он не работает в Windows. По этой причине, while True: sleep(1)
может быть лучшим вариантом.
Для некоторого фона объекты Event
обычно используются для ожидания завершения длительных процессов:
def do_task():
sleep(10)
print('Task complete.')
event.set()
event = Event()
Thread(do_task).start()
event.wait()
print('Continuing...')
Какие принты:
Task complete.
Continuing...
Ответ 6
Запуск метода в качестве фонового потока со сном в Python
import threading
import time
class ThreadingExample(object):
""" Threading example class
The run() method will be started and it will run in the background
until the application exits.
"""
def __init__(self, interval=1):
""" Constructor
:type interval: int
:param interval: Check interval, in seconds
"""
self.interval = interval
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
def run(self):
""" Method that runs forever """
while True:
# Do something
print('Doing something imporant in the background')
time.sleep(self.interval)
example = ThreadingExample()
time.sleep(3)
print('Checkpoint')
time.sleep(2)
print('Bye')
Ответ 7
signal.pause()
- другое решение, см. https://docs.python.org/3/library/signal.html#signal.pause
Заставить процесс спать до получения сигнала; будет вызван соответствующий обработчик. Ничего не возвращает Не в Windows. (См. Сигнал справочной страницы Unix (2).)