Pythonでタイミングタスクを実装する4つの方法

最近、私は主に背景部分の開発を担当する小さなプログラム開発タスクを実行しました。プロジェクトのニーズに応じて、3つの時間指定タスクを実装する必要があります。

WeChatトークンを定期的に更新します。これは2時間ごとに更新する必要があります。
商品は定期的にオンラインです。
バックグラウンドサービスが稼働しているかどうかを定期的に確認してください。

多くの人がPythonを学び、基本的な文法を習得した後、どこから始めればよいかわかりません。

事例研究を行った多くの人々は、より高度な知識を学ぶ方法を知りません。

したがって、これら3つのタイプの人々のために、ビデオチュートリアル、電子書籍、およびコースのソースコードを無料で受け取ることができる優れた学習プラットフォームを提供します。

QQグループ:701698587

ここに画像の説明を挿入

Pythonを使用してこれらの3つのタスクを実装するには、ここでタイミング関連のナレッジポイントを使用する必要があります
。Pythonには固定小数点タスクとタイミングタスクを実装する方法が他にもあります。次の4つの実装方法を見つけてください。それぞれに、独自のアプリケーションシナリオがあります。タイミングタスクのPython実装で一般的に使用される簡単な紹介です。

1.ループ+スリープ;

2.スレッドモジュールのTimerクラス。

3.モジュールをスケジュールします。

4.タイミングフレームワーク:APScheduler

開始する前に、タスクを設定します(外部環境に依存する必要がないように)。

1:CPUとメモリの使用状況を定期的または固定的に監視します。

2:時間、CPU、およびメモリ使用量をログファイルに保存します。

システム監視機能を最初に実装する:
準備:psutilのインストール:pipインストールpsutil
機能の実現

#psutil:システム情報モジュールを取得します。CPU、メモリ、ディスクなどの使用状況を取得できます。

import psutil
import time
import datetime
#logfile:监测信息写入文件
def MonitorSystem(logfile = None):
 #获取cpu使用情况
 cpuper = psutil.cpu_percent()
 #获取内存使用情况:系统内存大小,使用内存,有效内存,内存使用率
 mem = psutil.virtual_memory()
 #内存使用率
 memper = mem.percent
 #获取当前时间
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 line = f'{ts} cpu:{cpuper}%, mem:{memper}%'
 print(line)
 if logfile:
 logfile.write(line)



コード実行結果:

2019-03-21 14:23:41 cpu:0.6%, mem:77.2%



次に、システムリソースの使用状況を監視するために、3秒などの定期的な監視を実装する必要があります。

使用する最も簡単な方法:睡眠

この方法は最も簡単で、while + sleepを使用して直接実行できます。

def loopMonitor():
 while True:
 MonitorSystem()
 #2s检查一次
 time.sleep(3)
loopMonitor()



出力結果:

2019-03-21 14:28:42 cpu:1.5%, mem:77.6%
2019-03-21 14:28:45 cpu:1.6%, mem:77.6%
2019-03-21 14:28:48 cpu:1.4%, mem:77.6%
2019-03-21 14:28:51 cpu:1.4%, mem:77.6%
2019-03-21 14:28:54 cpu:1.3%, mem:77.6%



このアプローチには問題があります。単一のタイミングタスクしか処理できません。

ここに新しいタスクがあります。毎秒バイトを送受信するネットワークを監視する必要があります。コードは次のように実装されます。

def MonitorNetWork(logfile = None):
 #获取网络收信息
 netinfo = psutil.net_io_counters()
 #获取当前时间
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 line = f'{ts} bytessent={netinfo.bytes_sent}, bytesrecv={netinfo.bytes_recv}'
 print(line)
 if logfile:
 logfile.write(line)
MonitorNetWork()



コード実行結果:

2019-03-21 14:47:21 bytessent=169752183, bytesrecv=1107900973



whileループ内の2つのタスクを同時に監視すると、待機の問題が発生し、ネットワークの状況を毎秒監視できなくなります。

タイマーの実装

タイマーの最も基本的な理解はタイマーです。複数のタイミングタスクを開始できます。これらのタイマータスクは非同期で実行されるため、待機順序の実行の問題はありません。

まず、タイマーの基本的な使用法を見てみましょう。

インポート:

from threading import Timer

主な方法:

タイマーメソッドの説明Timer(interval、function、args = None、kwargs = None)タイマーの作成cancel()タイマーのキャンセルstart()スレッドモードを使用してjoin(self、timeout = None)を実行しますスレッドの実行が終了するのを待ちます

タイマーは1回しか実行できません。繰り返し実行する必要がある場合は、タスクを再度追加する必要があります。

まず、基本的な使用法を見てみましょう。

from threading import Timer
#记录当前时间
print(datetime.datetime.now())
#3S执行一次
sTimer = Timer(3, MonitorSystem)
#1S执行一次
nTimer = Timer(1, MonitorNetWork)
#使用线程方式执行
sTimer.start()
nTimer.start()
#等待结束
sTimer.join()
nTimer.join()
#记录结束时间
print(datetime.datetime.now())



出力結果:

2019-03-21 15:13:36.739798
2019-03-21 15:13:37 bytessent=171337324, bytesrecv=1109002349
2019-03-21 15:13:39 cpu:1.4%, mem:93.2%
2019-03-21 15:13:39.745187



ご覧のとおり、3Sの時間がかかりますが、私たちがやりたいのは、ネットワークの状態を毎秒監視することです。

タイマーは1回しか実行できないため、実行が完了したら、タスクを再度追加する必要があります。コードを変更します。

from threading import Timer
import psutil
import time
import datetime
def MonitorSystem(logfile = None):
 cpuper = psutil.cpu_percent()
 mem = psutil.virtual_memory()
 memper = mem.percent
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 line = f'{ts} cpu:{cpuper}%, mem:{memper}%'
 print(line)
 if logfile:
 logfile.write(line)
 #启动定时器任务,每三秒执行一次
 Timer(3, MonitorSystem).start()
def MonitorNetWork(logfile = None):
 netinfo = psutil.net_io_counters()
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 line = f'{ts} bytessent={netinfo.bytes_sent}, bytesrecv={netinfo.bytes_recv}'
 print(line)
 if logfile:
 logfile.write(line)
 #启动定时器任务,每秒执行一次
 Timer(1, MonitorNetWork).start()
MonitorSystem()
MonitorNetWork()



結果:

2019-03-21 15:18:21 cpu:1.5%, mem:93.2%
2019-03-21 15:18:21 bytessent=171376522, bytesrecv=1109124678
2019-03-21 15:18:22 bytessent=171382215, bytesrecv=1109128294
2019-03-21 15:18:23 bytessent=171384278, bytesrecv=1109129702
2019-03-21 15:18:24 cpu:1.9%, mem:93.2%
2019-03-21 15:18:24 bytessent=171386341, bytesrecv=1109131110
2019-03-21 15:18:25 bytessent=171388527, bytesrecv=1109132600
2019-03-21 15:18:26 bytessent=171390590, bytesrecv=1109134008



この2つのタスクを同時に実行でき、待機の問題がないことがわかります。

タイマーの本質は、スレッドを使用してタスクを実行することです。タスクは実行のたびに破棄されるため、リソースの問題について心配する必要はありません。

スケジューリングモジュール:スケジュール

スケジュールは、秒、分、時間、日付、またはカスタムイベントに従って時間を実行できるサードパーティの軽量タスクスケジューリングモジュールです。

インストール方法:

pip install schedule

例を見てみましょう:

import datetime
import schedule
import time
def func():
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 print('do func time :',ts)
def func2():
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 print('do func2 time:',ts)
def tasklist():
 #清空任务
 schedule.clear()
 #创建一个按秒间隔执行任务
 schedule.every(1).seconds.do(func)
 #创建一个按2秒间隔执行任务
 schedule.every(2).seconds.do(func2)
 #执行10S
 for i in range(10):
 schedule.run_pending()
 time.sleep(1)
tasklist()



結果:

do func time : 2019-03-22 08:51:38
do func2 time: 2019-03-22 08:51:39
do func time : 2019-03-22 08:51:39
do func time : 2019-03-22 08:51:40
do func2 time: 2019-03-22 08:51:41
do func time : 2019-03-22 08:51:41
do func time : 2019-03-22 08:51:42
do func2 time: 2019-03-22 08:51:43
do func time : 2019-03-22 08:51:43
do func time : 2019-03-22 08:51:44
do func2 time: 2019-03-22 08:51:45
do func time : 2019-03-22 08:51:45
do func time : 2019-03-22 08:51:46



実行プロセス分析:

1> Jupyterで実行されるため、最初にスケジュールタスクをクリアします
。2>時間に従ってスケジュールにタスクを追加します
。3> 2番目の間隔に従ってfuncを追加し、2秒間隔に従ってfunc2を追加します
。4>後スケジュールはタスクを追加します。タスクをクエリしてタスクを実行する必要があります
。5>リソースの占有を防ぐために、毎秒ポイントタスクにクエリを実行し、それらを順番に実行します。

5次実行を理解する方法として、func関数を変更し、time.sleep(2)を追加します。

次に、funcジョブを実行して、結果を出力します。

do func time : 2019-03-22 09:00:59
do func time : 2019-03-22 09:01:02
do func time : 2019-03-22 09:01:05



時間間隔が3Sであることがわかりますが、なぜ1Sではないのでしょうか。

これは順番に実行されるため、funcは2Sでスリープし、循環タスククエリは1Sでスリープするため、この問題が発生します。

この方法を使用してタスクを実行する場合は、このブロッキング現象に注意する必要があります。

スケジュールモジュールの一般的な使用法を見てみましょう。

#schedule.every(1)创建Job, seconds.do(func)按秒间隔查询并执行
schedule.every(1).seconds.do(func)
#添加任务按分执行
schedule.every(1).minutes.do(func)
#添加任务按天执行
schedule.every(1).days.do(func)
#添加任务按周执行
schedule.every().weeks.do(func)
#添加任务每周1执行,执行时间为下周一这一时刻时间
schedule.every().monday.do(func)
#每周1,1点15开始执行
schedule.every().monday.at("12:00").do(job)



このアプローチの制限:作業タスクに非常に時間がかかる場合、他のタスクの実行に影響します。並行性メカニズムを使用してこのモジュールを構成することを検討できます。

タスクフレームワークAPScheduler

APSchedulerは、Pythonの時限タスクフレームワークであり、定期的または時限タスクを実行するために使用されます。

これは、Linuxのcrontabタイプのタイミングタスクと同様に、日付、時間間隔、およびタイミングタスクに基づくことができます。

フレームワークは、時限タスクを追加および削除できるだけでなく、タスクをデータベースに保存して、タスクの永続性を実現することもできます。これは非常に便利です。

インストール方法:

pip install apscheduler

Apschedulerコンポーネントと簡単な手順:

1>トリガー(トリガー):トリガーにはスケジューリングロジックが含まれ、各ジョブには独自のトリガーがあります
2>ジョブストア(ジョブストレージ):スケジュールされたジョブを格納するために使用されます。デフォルトのジョブストアは、単にジョブタスクを格納することですメモリに格納され、ストレージをサポートしますMongoDBでは、Redisデータベース
3> executors(executors):executorsはタイミングタスクを実行するために使用されますが、実行する必要のあるタスクは、
4>スケジューラー(スケジューラー)を実行するために新しいスレッドまたはスレッドプールに配置されます):スケジューラーリンク他の部分を一緒に使用して、ユーザーにインターフェイスを提供し、タスクの追加、設定、および削除を実行します。私たちのPython学習控除qun:784、758、214、前任者がどのように学習するかを見てください!経験の交換!
簡単な例を見てみましょう。

import time
from apscheduler.schedulers.blocking import BlockingScheduler
def func():
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 print('do func time :',ts)
def func2():
 #耗时2S
 now = datetime.datetime.now()
 ts = now.strftime('%Y-%m-%d %H:%M:%S')
 print('do func2 time:',ts)
 time.sleep(2)
def dojob():
 #创建调度器:BlockingScheduler
 scheduler = BlockingScheduler()
 #添加任务,时间间隔2S
 scheduler.add_job(func, 'interval', seconds=2, id='test_job1')
 #添加任务,时间间隔5S
 scheduler.add_job(func2, 'interval', seconds=3, id='test_job2')
 scheduler.start()
dojob()



出力結果:

do func time : 2019-03-22 10:32:20
do func2 time: 2019-03-22 10:32:21
do func time : 2019-03-22 10:32:22
do func time : 2019-03-22 10:32:24
do func2 time: 2019-03-22 10:32:24
do func time : 2019-03-22 10:32:26



出力結果から、タスクが遅れても他のタスクの実行には影響しないことがわかります。

APSchedulerフレームワークは、タイミングタスクを実装するための豊富なインターフェイスを提供します。公式ドキュメントを参照して、それらの使用方法を確認できます。

最終的な選択:

上記の4つの固定小数点タスクの実装を簡単に要約します。

1:ループ+スリープモードは、ショートアンサーテストに適しています。

2:タイマーはタイミングタスクを実装できますが、固定小数点タスクの場合は、現在の時点を確認する必要があります。

3:スケジュールは固定されたポイントとタイミングで実行できますが、タスクはループ内で検出される必要があり、ブロックがあります。

4:APSchedulerフレームワークはより強力であり、固定小数点タスクとタイミングタスクを直接追加できます。

包括的な考慮事項に基づいて、実装が簡単で、タスクを直接作成してスケジューラーに追加するだけでよいAPSchedulerフレームワークを使用することにしました。
 

おすすめ

転載: blog.csdn.net/Python_kele/article/details/115285018