시간 및 날짜/시간 모듈을 사용하여 규칙적인 시간 간격 자습서로 실행되는 Python 프로그램

이 자습서에서는 time 및 datetime 모듈을 사용하여 정기적인 시간 간격으로 실행되도록 Python 프로그램을 설정하는 방법을 알려줍니다. 이것은 무언가를 지속적으로 확인하려는 경우에 유용하므로 백그라운드에서 정기적으로 확인을 수행하는 Python 프로그램이 있습니다.

해결책



솔루션을 맨 위에 놓을 것입니다. 내가 그것을 어떻게 찾았는지에 관심이 있다면 아래에서 그것에 대해 읽을 수 있습니다.

당신이 하는 일이 가벼운 경우를 위한 간단한 솔루션



경량은 단순한 인쇄 기능처럼 많은 CPU 전력과 시간을 사용하지 않는다는 것을 의미합니다.

10초마다 코드를 실행한다고 가정합니다.

import time
from datetime import datetime

def do_things():
    print(datetime.now())

while True:
    do_things()
    time.sleep(10)



당신은 이것과 같은 것을 얻어야합니다

2022-08-24 10:59:35.247516
2022-08-24 10:59:45.259224
2022-08-24 10:59:55.272715
2022-08-24 11:00:05.284097
2022-08-24 11:00:15.290823



여기에서 다른 간격을 원하면 수면 시간을 바꿀 수 있고 do_things() 함수의 내용을 프로그램에서 원하는 것으로 바꿀 수 있습니다.

간단한 해결책의 문제



그러나 당신이 나와 같다면 다른 프로그램에서 I/O를 기다리는 것이든 CPU 집약적인 작업을 하는 것이든 매 간격마다 수행하려는 작업에 시간이 걸립니다. 그런 다음 우리가 한 일을 계속하면 아래와 같이 대기 시간이 부정확해집니다.

import time
from datetime import datetime

def do_things():
    number = 50_000_000
    sum(i*i for i in range(number))
    print(datetime.now())

while True:
    do_things()
    time.sleep(10)



여기서는 sum(i*i for i in range(number))를 엄청난 숫자로 사용하여 CPU가 많은 작업을 수행하도록 했습니다.

2022-08-24 11:07:54.377208
2022-08-24 11:08:07.599538
2022-08-24 11:08:20.838108
2022-08-24 11:08:34.043164
2022-08-24 11:08:47.255688



보시다시피 우리는 프로그램이 10초마다 실행되기를 원하지만 각 루프마다 프로그램이 약 14초 걸렸습니다. 고급 솔루션이 필요한 이유입니다.

고급 솔루션




import time
from datetime import datetime, timedelta

def do_things():
    number = 50_000_000
    sum(i*i for i in range(number))
    print(datetime.now())

while True:
    previous_datetime = datetime.now()
    do_things()
    time_took_running_do_things = datetime.now() - previous_datetime
    remaining_time_in_secs = (timedelta(seconds=10) - time_took_running_do_things).total_seconds()
    time.sleep(remaining_time_in_secs)



결과는 다음과 같습니다.

2022-08-24 11:14:40.821099
2022-08-24 11:14:50.797054
2022-08-24 11:15:00.806950
2022-08-24 11:15:10.834795
2022-08-24 11:15:20.845102



설명



여기에서 무거운 작업을 수행하고 있음에도 불구하고 코드가 10초마다 실행되는 것을 볼 수 있습니다. 이는 do_things()를 실행하는 데 걸리는 시간을 less를 기다리면서 보상했기 때문입니다. 프로그램이 do_things()를 실행하는 데 3초가 걸린다면 이후에 7초만 기다리므로 프로그램은 여전히 ​​10초마다 작업을 수행합니다.

한정



이 솔루션은 수행하려는 작업이 반복하려는 간격보다 오래 걸리도록 제한됩니다. 1초마다 10초가 걸리는 작업을 수행하려는 경우 이 솔루션이 도움이 되지 않습니다. Concurrency from this RealPython article을 살펴보고 싶을 수도 있습니다.

내가 어떻게 거기에 도착



이제 내가 이것을 알아낸 방법에 대해 이야기하겠습니다.

a program that sees if I'm playing computer games at regular intervals to remind myself how long I'm playing 작업을 하고 있는데 문제는 매우 부정확하다는 것입니다. 45분 동안 게임을 하면 프로그램에서 30분만 플레이했다고 알려줍니다.

처음에는 이것이 time.sleep()의 문제라고 생각했습니다. 아마도 게임 중에 CPU가 많은 작업을 수행하기 때문에 대기 시간이 잘못된 것일 수 있습니다.

그러나 이것은 내가 게임을 하지 않을 때 프로그램이 여전히 잘못된 간격으로 실행된다는 점에서 잘못된 것으로 입증되었습니다.

그런 다음 프로그램이 각 간격 내에서 수행하는 작업을 주석 처리하고 인쇄 시간 문만 남기고 문제가 해결되었습니다. 문제는 간격 내에서 수행하는 작업이 2초 이상 소요된다는 것입니다!

그런 다음 즉시 문제를 과도하게 엔지니어링하려고 시도했습니다. 루프와 do_things() 함수가 스레딩이나 asyncio를 통해 별도의 스레드에 있거나 멀티프로세싱을 사용하는 별도의 CPU를 원할 수도 있다고 생각했습니다. 이 그래프를 그리기 전까지 Speed Up Your Python Program With Concurrency by Jim Anderson on RealPython의 전체 튜토리얼을 시청했습니다.



그런 다음 깨달았습니다. 모든 것을 선형으로 수행한 다음 기다려야 하는 시간을 계산하면 어떻게 될까요? 문제가 결코 이렇게 복잡하지 않다는 것을 그때 깨달았습니다. 그래서 문제를 해결하고 저와 같은 다른 사람들을 돕기 위해 이 글을 쓰기로 결정했습니다. 그래서 당신은 그것을 가지고 있습니다.

좋은 웹페이지 즐겨찾기