Wie kann man das Python-Programm für immer ausführen?


85

Ich muss mein Python-Programm für immer in einer Endlosschleife ausführen.

Derzeit leite ich es so -

#!/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)

Gibt es einen besseren Weg, dies zu tun? Oder brauche ich überhaupt einen time.sleepAnruf? Irgendwelche Gedanken?


Das wäre der richtige Weg. Sie brauchen das nicht time.sleep(5), solange Sie einen Code unter der while True:Zeile eingerückt haben (es kann nur passein Minimum sein)
Holy Mackerel

1
Es ist gut, eine Unterbrechungsbedingung hinzuzufügen - "Shutdown Hook", wenn Sie beenden möchten, anstatt den Prozess abzubrechen.
user3020494

7
Wenn Sie jedoch nicht schlafen oder etwas tun, das für ein externes Ereignis schläft (z. B. auf Verbindungen oder Daten an einem Socket warten ), verwendet Ihr Programm 100% CPU, auch bekannt als Busywait . Dies ist nicht höflich :)
Qris

Python 3.5 kann Asyncio verwenden und Funktionen an Ereignisse binden. Programm mit GUI kann mit ui-event loop (zum Beispiel gtk.main ()) umgehen
eri

Dies scheint ein Duplikat dieser Frage zu sein: stackoverflow.com/questions/3226628/non-blocking-wait-in-python
dllahr

Antworten:


102

Ja, Sie können eine while True:Schleife verwenden, die niemals unterbrochen wird, um Python-Code kontinuierlich auszuführen.

Sie müssen jedoch den Code, den Sie kontinuierlich ausführen möchten, in die Schleife einfügen :

#!/usr/bin/python

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

Wird auch time.sleepverwendet, um den Betrieb eines Skripts für einen bestimmten Zeitraum anzuhalten. Da Sie also möchten, dass Ihre kontinuierlich ausgeführt werden, verstehe ich nicht, warum Sie sie verwenden würden.


während True nicht zu funktionieren scheint, wenn Python-Code über eine .bat-Datei
gestartet wird

1
Kann time.sleepdie Leistung verbessert werden, indem beispielsweise 1 ms gewartet wird, anstatt mit maximaler Geschwindigkeit zu laufen?
538ROMEO

36

Wie wäre es mit diesem?

import signal
signal.pause()

Dadurch wird Ihr Programm in den Ruhezustand versetzt, bis es ein Signal von einem anderen Prozess (oder von sich selbst in einem anderen Thread) empfängt und es weiß, dass es Zeit ist, etwas zu tun.


2
Das Signal stoppt den Thread. Bei Title geht es darum, für immer zu laufen. Wie Systemdienst oder Daemon.
Outoftime

1
Würde das nur den Hauptthread stoppen und anderen Threads erlauben, unbegrenzt zu laufen?
David V.

@ David Ja, dies stoppt nur den Haupt-Thread. Ich habe gerade getestet, um zu bestätigen.
Samuel

9

Schlaf ist ein guter Weg, um eine Überlastung der CPU zu vermeiden

Ich bin mir nicht sicher, ob es wirklich klug ist, aber ich benutze es normalerweise

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

Die Schlafmethode gibt immer None zurück.


ohne Kommentar abgelehnt? Ich mochte diese Lösung, als ich sie las, weil sie eine gute Lesbarkeit / Wartbarkeit hat. Ein interessierter Leser dieses Codes muss nicht scrollen, um das Schleifenintervall zu finden.
Matt

1
@mustafa welches? Erkläre dich selbst, es funktioniert einwandfrei.
Porunga

1
schläft es nicht vor der ersten Hinrichtung? Ich denke nicht, dass es allgemein erwünschtes Verhalten ist
noonex

7

Ich weiß, dass dies ein zu alter Thread ist, aber warum hat das niemand erwähnt?

#!/usr/bin/python3
import asyncio 

loop = asyncio.get_event_loop()
try:
    loop.run_forever()
finally:
    loop.close()

1
Ich benutze dies immer, wenn ich versuche, mein Programm für immer laufen zu lassen. Ich weiß auch nicht, warum das niemand erwähnt hat
madladzen

5

für Betriebssysteme, die Folgendes unterstützen select:

import select

# your code

select.select([], [], [])

5

Hier ist die vollständige Syntax:

#!/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

1

Ich habe ein kleines Skript interruptableloop.py , das den Code in einem Intervall (Standard 1 Sek.) Ausführt, während der Ausführung eine Nachricht auf den Bildschirm pumpt und ein Interrupt-Signal abfängt, das Sie mit CTL-C senden können:

#!/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

Wenn Sie das Skript ausführen und dann unterbrechen, sehen Sie diese Ausgabe (die Perioden werden bei jedem Durchlauf der Schleife abgepumpt):

[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

Wäre es nicht viel einfacher (und pythonischer), nur die KeyboardInterruptund SystemExitAusnahmen im Client-Code abzufangen , als eine eigene Klasse dafür zu haben?
Matthew Cole

Ich benutze dies für die Kapselung und ich mag die Art und Weise, wie es liest. Offensichtlich geht mir die Implementierung von Interruptableloop nicht durch den Kopf, wenn ich es benutze.
Riaz Rizvi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.