Як запустити програму 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як мінімум)
Свята Скумбрія

1
Добре додати умову перерви - "гачок відключення", якщо ви хочете вийти, а не вбивати процес.
user3020494

7
Але якщо ви не спите або робите щось, що спить для зовнішньої події (наприклад, прослуховування з'єднань або даних на сокеті), тоді ваша програма буде використовувати 100% процесор, він же зайнятий . Це не чемно :)
qris

Python 3.5 може використовувати asyncio та прив'язувати функції до подій. Програма з графічним інтерфейсом може мати справу з циклом ui-подій (наприклад, 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

37

Як щодо цього?

import signal
signal.pause()

Це дозволить вашій програмі спати, поки вона не отримає сигнал від якогось іншого процесу (або від самого себе, в іншому потоці), даючи їй зрозуміти, що час щось робити.


2
Сигнал зупинить потік. Назва - це про біг назавжди. Як системна служба чи демон.
вихідний час

1
це зупинило б лише основний потік, дозволивши іншим потокам працювати необмежено довго?
Девід В.

@David Так, це зупиняє лише основний потік. Я просто перевірив, щоб підтвердити.
Самуель

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

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

Чи не буде набагато простіше (і більш пітонічним) просто вловити KeyboardInterruptі SystemExitвинятки в коді клієнта, а не мати для цього виділений клас?
Метью Коул

Я використовую це для інкапсуляції, і мені подобається, як це читається. Очевидно, що реалізація interruptableloop не згадується у мене під час використання.
Riaz Rizvi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.