ホームページ >バックエンド開発 >Python チュートリアル >Python がシグナル モジュールを使用してスケジュールされた実行メソッドを実装する方法の詳細な説明
liunx システムでは、コマンドを毎分実行したい場合、最も一般的な方法は crontab です。 crontab を使用したくない場合は、timer を使用してこの機能を実現できると同僚が指摘しました。プログラムを調べ始めたので、シグナルについての知識が必要であることがわかりました...
あなたの linux がどのシグナルをサポートしているかを確認してください: kill -l
root@server:~# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX root@server:~#
シグナル: プロセス間の通信方法です。ソフトウェア割り込み。プロセスがシグナルを受信すると、元のプログラムの実行フローを中断してシグナルを処理します。オペレーティング システムは、シグナル受信後のプロセスのデフォルトの動作を規定していますが、シグナル処理関数をバインドすることで、シグナル受信後のプロセスの動作を変更できます。SIGTOP と SIGKILL という 2 つのシグナルがあります。
シグナルを送信する理由は通常 2 つあります:
1 (パッシブ) たとえば、子プロセスが終了すると、カーネルは親プロセスに SIGCHLD シグナルを送信します。キーボードの c は SIGINT シグナルを送信します 2 (アクティブ) システムコール kill を通じて指定されたプロセスにシグナルを送信します
C 言語
には setitimer 関数があり、関数 setitimer は次の 3 つのタイマーを提供できます。相互に独立して、時間が完了するとタイミング信号がプロセスに送信され、自動的に時間が再開されます。タイマーのタイプを決定するパラメータ: ITIMER_REAL アラームのタイプと同じ、タイミングのリアルタイム。 SIGALRM
ITIMER_VIRT ユーザーモードでのスケジュールされたプロセスの実際の実行時間。 SIGVTALRM
ITIMER_PROF ユーザー モードおよびコア モードでのスケジュールされたプロセスの実際の実行時間。 SIGPROF
3 種類のタイマーは、計時完了時にプロセスに異なる信号を送信します。そのうち、ITIMER_REAL クラスのタイマーは SIGALRM 信号を送信し、ITIMER_VIRT クラスのタイマーは SIGVTALRM 信号を送信し、ITIMER_REAL クラスのタイマーは SIGPROF 信号を送信します。 。
アラーム関数は基本的に、低精度で過負荷になっていない ITIMER_REAL タイマーを設定します。精度は秒単位までであり、タイミングは設定ごとに 1 回しか生成できません。関数 setitimer で設定されるタイマーは、(理論上) マイクロ秒単位で時間を計ることができるだけでなく、自動的に
loopすることもできます。 Unix プロセスでは、アラーム タイマーと ITIMER_REAL タイマーを同時に使用することはできません。 SIGINT プロセスの終了 プロセスの中断 (control+c)
SIGTERM プロセスの終了 ソフトウェア終了信号
SIGKILL プロセスの終了 プロセスの強制終了
SIGALRM 目覚まし時計信号
予備知識はほぼ準備ができたので、
pythonsignal パッケージは、各信号名とそれに対応する
integer を定義します。たとえば、import signal
print signal.SIGALRM
print signal.SIGCONT
Python で使用される信号名は Linux と一致します。
$man 7 signal
を介して
プリセット信号処理関数をクエリできます。signal パッケージの中核は、以下に示すように、signal.signal() 関数を使用して信号処理関数をプリセット (登録) することです。は特定のシグナル、handlerはシグナルの処理関数です。シグナルの基本で、プロセスがシグナルを無視したり、デフォルトのアクションを実行したり、アクションをカスタマイズしたりできることを説明しました。ハンドラーが signal.SIG_IGN の場合、シグナルは無視されます。ハンドラーが singal.SIG_DFL の場合、プロセスはデフォルトのアクション (デフォルト) を実行します。 handler が関数名の場合、プロセスは関数で定義されたアクションを実行します。
singnal.signal(signalnum, handler)
メインプログラムでは、まず signal.signal() 関数を使用して信号処理関数をプリセットします。次に、signal.pause() を実行して、シグナルを待っているプロセスを一時停止してシグナルを待ちます。シグナル SIGUSR1 がプロセスに渡されると、プロセスは一時停止から再開し、デフォルトに従って SIGTSTP シグナル処理関数 myHandler() を実行します。 myHandler の 2 つのパラメータのうち 1 つはシグナル (signum) を識別するために使用され、もう 1 つはシグナル発生時のプロセス スタックのステータス (スタック フレーム) を取得するために使用されます。どちらのパラメータも signal.singnal() 関数によって渡されます。
上面的程序可以保存在一个文件中(比如test.py)。我们使用如下方法运行:
$python test.py
以便让进程运行。当程序运行到signal.pause()的时候,进程暂停并等待信号。此时,通过按下CTRL+Z向该进程发送SIGTSTP信号。我们可以看到,进程执行了myHandle()函数, 随后返回主程序,继续执行。(当然,也可以用$ps查询process ID, 再使用$kill来发出信号。)
(进程并不一定要使用signal.pause()暂停以等待信号,它也可以在进行工作中接受信号,比如将上面的signal.pause()改为一个需要长时间工作的循环。)
我们可以根据自己的需要更改myHandler()中的操作,以针对不同的信号实现个性化的处理。
定时发出SIGALRM信号
一个有用的函数是signal.alarm(),它被用于在一定时间之后,向进程自身发送SIGALRM信号:
import signal # Define signal handler function def myHandler(signum, frame): print("Now, it's the time") exit() # register signal.SIGALRM's handler signal.signal(signal.SIGALRM, myHandler) signal.alarm(5) while True: print('not yet')
我们这里用了一个无限循环以便让进程持续运行。在signal.alarm()执行5秒之后,进程将向自己发出SIGALRM信号,随后,信号处理函数myHandler开始执行。
发送信号
signal包的核心是设置信号处理函数。除了signal.alarm()向自身发送信号之外,并没有其他发送信号的功能。但在os包中,有类似于linux的kill命令的函数,分别为
os.kill(pid, sid) os.killpg(pgid, sid)
分别向进程和进程组(见Linux进程关系)发送信号。sid为信号所对应的整数或者singal.SIG*。
实际上signal, pause,kill和alarm都是Linux应用编程中常见的C库函数,在这里,我们只不过是用Python语言来实现了一下。实际上,Python 的解释器是使用C语言来编写的,所以有此相似性也并不意外。此外,在Python 3.4中,signal包被增强,信号阻塞等功能被加入到该包中。我们暂时不深入到该包中。
以上がPython がシグナル モジュールを使用してスケジュールされた実行メソッドを実装する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。