ホームページ  >  記事  >  バックエンド開発  >  Python がシグナル モジュールを使用してスケジュールされた実行メソッドを実装する方法の詳細な説明

Python がシグナル モジュールを使用してスケジュールされた実行メソッドを実装する方法の詳細な説明

高洛峰
高洛峰オリジナル
2017-03-19 15:24:501380ブラウズ

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 目覚まし時計信号

予備知識はほぼ準備ができたので、

python

シグナルに報告する時間です行進した。 信号名の定義

signal パッケージは、各信号名とそれに対応する

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。