Как запустить программу Python вечно?

87

Мне нужно запускать мою программу Python вечно в бесконечном цикле.

В настоящее время я использую это так -

#!/usr/bin/python

import time

# some python code that I want 
# to keep on running


# Is this the right way to run the python program forever?
# And do I even need this time.sleep call?
while True:
    time.sleep(5)

Есть ли лучший способ сделать это? Или мне вообще нужен time.sleepзвонок? Есть предположения?

Алан В. Смит
источник
Это был бы правильный способ сделать это. Вам не нужен time.sleep(5), если у вас есть код с отступом под while True:строкой (он может быть passкак минимум)
Holy Mackerel
1
Если вы хотите завершить работу, лучше добавить условие прерывания - «ловушку выключения», чем убивать процесс.
user3020494
7
Но если вы не спите или делаете что-то, что спит для внешнего события (например, прослушивание соединений или данных в сокете), тогда ваша программа будет использовать 100% ЦП, также известный как busywait . Это невежливо :)
qris
Python 3.5 может использовать asyncio и связывать функции с событиями. Программа с графическим интерфейсом может обрабатывать цикл пользовательских событий (например, gtk.main ())
eri
Это похоже на дубликат этого вопроса: stackoverflow.com/questions/3226628/non-blocking-wait-in-python
dllahr

Ответы:

104

Да, вы можете использовать while True: цикл, который никогда не прерывается, для непрерывного выполнения кода Python.

Однако вам нужно будет поместить код, который вы хотите постоянно запускать, внутри цикла:

#!/usr/bin/python

while True:
    # some python code that I want 
    # to keep on running

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


источник
в то время как True, похоже, не работает при запуске кода Python через файл .bat
BarryMahnly
2
Можно ли time.sleepповысить производительность, подождав, например, 1 мс вместо работы на максимальной скорости?
grobouDu06 06
36

Как насчет этого?

import signal
signal.pause()

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

ревущий
источник
2
Сигнал остановит поток. Название о вечном беге. Как системная служба или демон.
вне времени
1
остановит ли это только основной поток, позволяя другим потокам работать бесконечно?
Дэвид В.
@David Да, это останавливает только основной поток. Я просто проверил, чтобы подтвердить.
Samuel
9

сон - хороший способ избежать перегрузки процессора

не уверен, что это действительно умно, но я обычно использую

while(not sleep(5)):
    #code to execute

Метод сна всегда возвращает None.

Порунга
источник
проголосовали против без комментариев? Мне понравилось это решение, когда я его прочитал, потому что у него хорошая читаемость / ремонтопригодность. Заинтересованному читателю этого кода не нужно прокручивать, чтобы найти интервал цикла.
Мэтт
1
@mustafa какой? объясните сами, он работает отлично.
Порунга
1
он не спит перед первой казнью? Я не думаю, что это вообще желаемое поведение
noonex
7

Я знаю, что это слишком старая ветка, но почему никто об этом не упомянул

#!/usr/bin/python3
import asyncio 

loop = asyncio.get_event_loop()
try:
    loop.run_forever()
finally:
    loop.close()
Эдж Голдберг
источник
1
Я всегда использую это, когда пытаюсь заставить мою программу работать вечно. Я тоже не знаю, почему об этом никто не упомянул
madladzen
5

для ОС, поддерживающих select:

import select

# your code

select.select([], [], [])
ГНР
источник
5

Вот полный синтаксис,

#!/usr/bin/python3

import time 

def your_function():
    print("Hello, World")

while True:
    your_function()
    time.sleep(10) #make function to sleep for 10 seconds
Balaji.JB
источник
1

У меня есть небольшой скрипт interruptableloop.py, который запускает код с интервалом (по умолчанию 1 секунда), выдает сообщение на экран во время работы и перехватывает сигнал прерывания, который вы можете отправить с помощью CTL-C:

#!/usr/bin/python3
from interruptableLoop import InterruptableLoop

loop=InterruptableLoop(intervalSecs=1) # redundant argument
while loop.ShouldContinue():
   # some python code that I want 
   # to keep on running
   pass

Когда вы запускаете скрипт, а затем прерываете его, вы видите этот вывод (периоды накачиваются на каждом проходе цикла):

[py36]$ ./interruptexample.py
CTL-C to stop   (or $kill -s SIGINT pid)
......^C
Exiting at  2018-07-28 14:58:40.359331

interruptableLoop.py :

"""
    Use to create a permanent loop that can be stopped ...

    ... from same terminal where process was started and is running in foreground: 
        CTL-C

    ... from same user account but through a different terminal 
        $ kill -2 <pid> 
        or $ kill -s SIGINT <pid>

"""
import signal
import time
from datetime import datetime as dtt
__all__=["InterruptableLoop",]
class InterruptableLoop:
    def __init__(self,intervalSecs=1,printStatus=True):
        self.intervalSecs=intervalSecs
        self.shouldContinue=True
        self.printStatus=printStatus
        self.interrupted=False
        if self.printStatus:
            print ("CTL-C to stop\t(or $kill -s SIGINT pid)")
        signal.signal(signal.SIGINT, self._StopRunning)
        signal.signal(signal.SIGQUIT, self._Abort)
        signal.signal(signal.SIGTERM, self._Abort)

    def _StopRunning(self, signal, frame):
        self.shouldContinue = False

    def _Abort(self, signal, frame):
        raise 

    def ShouldContinue(self):
        time.sleep(self.intervalSecs)
        if self.shouldContinue and self.printStatus: 
            print( ".",end="",flush=True)
        elif not self.shouldContinue and self.printStatus:
            print ("Exiting at ",dtt.now())
        return self.shouldContinue
Риаз Ризви
источник
Не было бы намного проще (и более Pythonic) просто поймать KeyboardInterruptи SystemExitисключений в коде клиента, а не иметь специальный класс для этого?
Мэтью Коул,
Я использую это для инкапсуляции, и мне нравится, как он читается. Очевидно, реализация interruptableloop не приходит мне в голову, когда я ее использую.
Риаз Ризви