django-apschedulerスケジュールされたタスク

apschedulerモジュールをインストールする

pip install apscheduler 
pip install django-apscheduler

プロジェクトの設定でdjango-apschedulerをINSTALLED_APPSに追加します

INSTALLED_APPS = [ 

   .... 

'django_apscheduler'、

]

実装:


#python manage.py migrate 他のテーブル構造ではpython manage.py makemigrationsを実行する必要はありません

2つのテーブルが作成されます:django_apscheduler_djangojob / django_apscheduler_djangojobexecution
は、バックグラウンド管理を入力することで、スケジュールされたタスクを簡単に管理できます。

Djangoプロジェクトディレクトリのurls.pyファイル、またはメインのurls.pyに、次のコンテンツを導入します

apscheduler.schedulers.background輸入BackgroundSchedulerから
django_apscheduler.jobstoresからDjangoJobStore、register_events、register_jobインポート

スケジューラ= BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore()、 "デフォルト") 

时间间隔3秒钟打印一次当前的时间
@register_job(スケジューラ、 "interval"、seconds = 3、id = 'test_job')
def test_job():
    print( "我是apscheduler任务")
#実行ごとのモニタリング、スケジューラで
register_eventsを呼び出すregister_events(scheduler)
scheduler.start()
print (「スケジューラが開始しました!」)

 

 

 結果は次のとおりです。

 

 

 

APSchedulerの2つのスケジューラーの違いと使用時に注意すべき問題

APSchedulerには多くの異なるタイプのスケジューラがあり、BlockingSchedulerとBackgroundSchedulerは最も一般的に使用される2つのスケジューラです。主な違いは、BlockingSchedulerはメインスレッドをブロックしますが、BackgroundSchedulerはブロックしません。したがって、さまざまな状況でさまざまなスケジューラを選択します。

  • BlockingScheduler:start関数を呼び出すと、現在のスレッドがブロックされます。(上記の例のように)スケジューラがアプリケーションで実行したい唯一のものである場合に使用されます。
  • BackgroundScheduler:startを呼び出した後、メインスレッドはブロックしません。他のフレームワークを実行しておらず、スケジューラをアプリケーションのバックグラウンドで実行する場合に使用します。

BlockingSchedulerの実際の例

from apscheduler.schedulers.blocking import BlockingScheduler 
import time 

def job():
    print( 'job 3s')


if __name __ == '__ main__':

    sched = BlockingScheduler(timezone = 'MST')
    sched.add_job(job、 'interval'、 id = '3_second_job'、seconds = 3)
    sched.start()

    while(True):
        print( 'main 1s')
        time.sleep(1)

运行结果:
ジョブ3s 
ジョブ3s 
ジョブ3s 
ジョブ3s

BlockingSchedulerstart関数呼び出すと現在のスレッドがブロックされ、メインプログラムのwhileループが実行されないことがわかります。

BackgroundScheduler実際の例

from apscheduler.schedulers.background import BackgroundScheduler 
import time 

def job():
    print( 'job 3s')


if __name __ == '__ main__':

    sched = BackgroundScheduler(timezone = 'MST')
    sched.add_job(job、 'interval'、 id = '3_second_job'、seconds = 3)
    sched.start()

    while(True):
        print( 'main 1s')
        time.sleep(1)

运行结果:
main 1s 
main 1s 
main 1s 
job 3s 
main 1s 
main 1s 
main 1s 
仕事3秒

BackgroundSchedulerstart関数を呼び出した後現在のスレッドがブロックされていないことがわかるので、メインプログラムのwhileループのロジックを続行できます。

この出力から、start関数を呼び出した後、job()がすぐに実行を開始しないこともわかります。代わりに、3秒待ってから実行がスケジュールされます。

ジョブを開始後に実行する方法()

スケジューラが開始関数を呼び出した直後に、ジョブ()をどのように実行できますか?

実際、APSchedulerこの問題を解決する良い方法はありませんが、次のように、スケジューラーの開始前にジョブ()を実行するのが最も簡単な方法の1つです。

from apscheduler.schedulers.background import BackgroundScheduler 
import time 

def job():
    print( 'job 3s')


if __name __ == '__ main__':
    job()
    sched = BackgroundScheduler(timezone = 'MST')
    sched.add_job(job、 ' interval '、id =' 3_second_job '、seconds = 3)
    sched.start()

    while(True):
        print(' main 1s ')
        time.sleep(1)


运行结果:
ジョブ3s 
メイン1s 
メイン1s 
メイン1s 
ジョブ3s 
メイン1秒
メイン1秒
メイン1秒

このように、「ジョブをstart()の後に開始させる」ことは絶対に可能ではありませんが、「スケジュールを待たずに、最初にジョブを実行する」こともできます。  

ジョブの実行時間が長すぎる場合

ジョブ()の実行時間が5秒かかるが、スケジューラがジョブ()を3秒ごとに呼び出すように構成されている場合、どうなりますか?次の例を書きました。

from apscheduler.schedulers.background import BackgroundScheduler 
import time 

def job():
    print( 'job 3s')
    time.sleep(5)

if __name __ == '__ main__':

    sched = BackgroundScheduler(timezone = 'MST')
    sched.add_job( job、 'interval'、id = '3_second_job'、seconds = 3)
    sched.start()

    while(True):
        print( 'main 1s')
        time.sleep(1)

运行结果:
main 1s 
main 1s 
main 1s 
job 3s 
main 1s 
main 1s 
main 1s 
ジョブ「job(trigger:interval [0:00:03]、next run at:2018-05-07 02:44:29 MST)」の実行がスキップされました:実行中のインスタンスの最大数に達した(1) 
メイン1
メイン1 
メイン1秒
ジョブ3秒
メイン1秒

3秒の時間が経過すると、「ジョブスレッドを再起動」せずに、スケジューリングをスキップして、次のサイクルを待機し(3秒待機)、ジョブを再スケジュールします()。

複数のジョブ()を同時に実行できるようにするために、スケジューラーのパラメーターを構成することもできます。max_instances次の例のように、2つのジョブ()を同時に実行できます。

from apscheduler.schedulers.background import BackgroundScheduler 
import time 

def job():
    print( 'job 3s')
    time.sleep(5)

if __name __ == '__ main__':
    job_defaults = {'max_instances':2} 
    sched = BackgroundScheduler(timezone = 'MST'、job_defaults = job_defaults)
    sched.add_job(job、 'interval'、id = '3_second_job'、seconds = 3)
    sched.start()

    while(True):
        print( 'main 1s')
        時間。スリープ(1) 

操作の結果
メイン1s 
メイン1s 
メイン1s 
ジョブ3s 
メイン1s 
メイン1s 
メイン1s 
ジョブ3s 
メイン1s 
メイン1s 
メイン1s 
ジョブ3s

各ジョブのスケジュール方法

上記の例を通して、スケジューラーはジョブ()関数を定期的にスケジュールして、スケジュールを達成することを発見しました。

ジョブ()関数はプロセスとして実行するようにスケジュールされますか、それともスレッドとして実行されますか?

この問題を明確にするために、次のプログラムを作成しました。

from apscheduler.schedulers.background import BackgroundScheduler 
import time、os、threading 

def job():
    print( 'job thread_id- {0}、process_id- {1}'。format(threading.get_ident()、os.getpid()) )
    time.sleep(50)

if __name __ == '__ main__':
    job_defaults = {'max_instances':20} 
    sched = BackgroundScheduler(timezone = 'MST'、job_defaults = job_defaults)
    sched.add_job(job、 'interval'、id = '3_second_job'、seconds = 3)
    sched.start()

    while(True):
        print( 'main 1s')
        time.sleep(1)

运行结結果:
main 1s 
main 1s 
main 1s 
ジョブthread_id-10644、process_id-8872 
main 1s 
main 1s
main 1s
job thread_id-3024、process_id-8872 
main 1s 
main 1s 
main 1s 
job thread_id-6728、process_id-8872 
main 1s 
main 1s 
main 1s 
job thread_id-11716、process_id-8872

各ジョブ()のプロセスIDは同じですが、スレッドIDが異なることがわかります。したがって、ジョブ()は最終的にスレッドの形で実行されるようにスケジュールされます。  

  

  

  

  

 

タスクをトリガーする方法の概要:

日付

from datetime import date 
from apscheduler.schedulers.blocking import BlockingScheduler 

sched = BlockingScheduler()

def my_job(text):
    print(text)

#在2030年04月21日执行
sched.add_job(my_job、 'date'、run_date = date(

2020、04、21 )、args = ['text'])sched.start()

前記run_dateパラメータの型は、日付、日付時刻型やテキスト型であってもよいです。

日時タイプ(正確な時間)


2009年11月6日16:30:05にsched.add_job(my_job、 'date'、run_date = datetime(2009、11、6、16、30、5)、args = ['text'])を実行します

  

  

  

  

  

  

おすすめ

転載: www.cnblogs.com/weidaijie/p/12747685.html