본문 바로가기
Programming/Python

[ Python ] 파이썬 스케줄러 작성하기(APScheduler) - BlockingScheduler | 파이썬 반복 작업 수행

by 코뮤(commu) 2021. 12. 14.
728x90
반응형

 

서버 위에서 항상 돌아가는 프로그램을 만드는 중이다.

해당 프로그램이 하위 프로세스를 만들어서 계속해서 어떤 동작을 수행 후 데이터를 출력하고 있다.

 

이때, while 문을 통해 해당 프로세스의 종료를 계속해서 확인하도록 작성했는데

이 while 문이 약간 불안하다고 하셨다.

 

휴지시간 없이 너무 cpu를 혹사시킬 것 같아 스케쥴러를 하나 두고

일정 시간동안 프로세스를 실행시키는 방식으로 바꿔보는 것은 어떠냐고 제안을 주셨다.

 

 

냉큼 받아들여서 바로 스케줄러를 작성해보고 있다.

생각보다 간단하고 강력한 것 같아 앞으로 여러곳에 써먹을 곳이 많을 것 같다.

 

이번 포스팅에서는 특정한 시간에 프로그램을 실행시키는 cron 이 아닌

일정 주기로 도는 interval 만 예시로 들 것 같다.

 

만약 특정 시간에 프로그램을 실행시키는 스케줄러가 필요하다면 구글에 apscheduler cron 과 같은 키워드로

검색해보시면 될 것 같다.

 

또한 스케줄러에 종류가 있다.

 

BlockingScheduler 와 BackgroundScheduler.

 

BackgroundScheduler 는 말그대로 백그라운드에서 실행된다.

해당 프로세스를 실행하면서 다른 프로세스도 계속해서 실행해야한다면 백그라운드스케줄러를 사용해야한다.

이번 포스팅에서는 단일 프로세스 실행이므로 BlockingSscheduler 를 사용한다.

 


 

우선 apscheduler 를 설치하자.

 

 

pip install apscheduler

 

 

이제 아래 코드를 살펴보자.

 

 

def job(data):
    print('data : ' + data)


def main():
    job('hello?')

if __name__ == "__main__":
    main()

 

 

hello? 를 출력하는 job을 실행시키는 아주 단순한 코드이다.

 

자, 이제 우리는 저 job 함수를 3초에 한번씩 실행시키고 싶다.

main 함수를 한번 실행하면, 'hello?' 를 실행시켜주는 job이 3초 간격으로 돌아가는 것이다.

 

 

아래 코드를 이런식으로 바꾸면 스케줄이 등록되어 우리가 하고자 하는 바를 달성할 수 있다.

 

 

from apscheduler.schedulers.background import BlockingScheduler

def job(data):
    print('data : ' + data)


def main():
    sched = BlockingScheduler()
    sched.add_job(job,'interval', seconds=3, id='test',args=['hello?'])
    sched.start()

if __name__ == "__main__":
    main()

 

실행하면 내가 프로그램을 종료하기 전까지는 계속해서 hello? 를 출력한다.

 

add_job 의 인수 중 'interval' 이 주기적으로 실행한다는 것을 알려주고 있다.

args 는 반드시 리스트의 형태를 띄고 있어야하며,

id값은 왜 있는지 궁금했는데 서칭해보니까 알 것 같다.

 

실행되는 job 함수가 10초 동안 실행되는 함수라고 가정해보자.

3초 뒤에 스케줄러가 job 함수를 실행하려하는데, 이미 id가 'test' 로 되어있는 함수가 실행중이라면?

시간이 겹치는 경우 이미 해당 task가 실행중인지 아닌지를 식별하기 위해 id 값이 존재하는 것 같다.

 

 

 

이런식으로 스케줄러를 컨트롤 할 수 있다.

 

근데 위 코드를 그대로 실행하면, 아마 아래와 같은 경고문이 출력될지도 모른다.

 

C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\apscheduler\util.py:95: PytzUsageWarning: The zone attribute is specific to pytz's interface; please migrate to a new time zone provider. For more details on how to do so, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html     
  if obj.zone == 'local':


C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\apscheduler\triggers\interval.py:66: PytzUsageWarning: The normalize method is no longer necessary, as this time zone supports the fold attribute (PEP 495). For more details on migrating to a PEP 495-compliant implementation, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
  return self.timezone.normalize(next_fire_time)

 

 

경로는 다를지도 모르겠지만, 아무튼 저런 경고가 나올 것이다.(나 같은 경우에는 리눅스에서도, 윈도우즈 환경에서도 둘 다 나왔다)

 

저건 timezone 설정하나로 해결 가능하다.

아까도 언급했듯이, cron 같이 특정 시간에 맞춰서 실행하는 것도 가능한 스케줄러 프로그램이라서 이런 경고문을 출력해주는 것 같다.

 

 

from apscheduler.schedulers.background import BlockingScheduler

def job(data):
    print('data : ' + data)


def main():
    sched = BlockingScheduler(timezone='Asia/Seoul')
    sched.add_job(job,'interval', seconds=3, id='test',args=['hello?'])
    sched.start()

if __name__ == "__main__":
    main()

 

 

위와 같이 timezone 설정을 해준다.

 

 

그럼 더이상 경고문은 보이지 않을 것이다!

 

 

728x90
반응형