Як запустити програму 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.