Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung, wie Python das Signalmodul verwendet, um geplante Ausführungsmethoden zu implementieren

Detaillierte Erläuterung, wie Python das Signalmodul verwendet, um geplante Ausführungsmethoden zu implementieren

高洛峰
高洛峰Original
2017-03-19 15:24:501436Durchsuche

Wenn Sie im Liunx-System jede Minute einen Befehl ausführen möchten, ist Crontab die häufigste Methode. Wenn Sie Crontab nicht verwenden möchten, haben Ihre Kollegen darauf hingewiesen, dass Sie Timer im Programm, um diese Funktion zu erreichen, also begann ich zu erforschen und stellte fest, dass ich einige Kenntnisse über Signale benötige...

Überprüfen Sie, welche Signale Ihr

Linux unterstützt: kill -l can

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:~#
Signal: Eine Kommunikationsmethode zwischen Prozessen, bei der es sich um einen Software-Interrupt handelt. Sobald ein Prozess ein Signal empfängt, unterbricht er den ursprünglichen Programmausführungsablauf, um das Signal zu verarbeiten. Das Betriebssystem legt das Standardverhalten des Prozesses nach dem Empfang des Signals fest. Wir können jedoch das Verhalten des Prozesses nach dem Empfang des Signals ändern, indem wir die Signalverarbeitungsfunktion binden. Es gibt zwei Signale, die nicht geändert werden können: SIGTOP und SIGKILL.

Es gibt im Allgemeinen zwei Gründe für das Senden von Signalen:

1 (Passiv) Der Kernel erkennt ein Systemereignis

, wenn beispielsweise der untergeordnete Prozess beendet wird. Es sendet SIGCHLD an den übergeordneten Prozess. Durch Drücken von Strg+c auf der Tastatur wird das SIGINT-Signal 2 (aktiv) gesendet. Das System ruft kill auf, um das Signal an den angegebenen Prozess zu senden 🎜> in der

C-Sprache

Es gibt eine Setitimer-Funktion. Die Funktion Setitimer kann drei voneinander unabhängige Timer bereitstellen. Bei Ablauf wird ein Zeitsignal an den Prozess gesendet Die Zeit wird automatisch neu eingestellt. Der Parameter, der den Typ des Timers bestimmt:

ITIMER_REAL Timing in Echtzeit, identisch mit dem Alarmtyp. SIGALRMITIMER_VIRT Die tatsächliche Ausführungszeit des geplanten Prozesses im Benutzermodus. SIGVTALRM

ITIMER_PROF Die tatsächliche Ausführungszeit des geplanten Prozesses im Benutzermodus und Kernmodus. SIGPROF

Diese drei Timer senden unterschiedliche Signale an den Prozess, wenn das Timing abgeschlossen ist. Darunter sendet der ITIMER_REAL-Klassen-Timer das SIGALRM-Signal, der ITIMER_VIRT-Klassen-Timer das SIGVTALRM-Signal und der ITIMER_REAL-Klassen-Timer SIGPROF-Signal.

Die Alarmfunktion stellt im Wesentlichen einen nicht überlasteten ITIMER_REAL-Timer mit geringer Genauigkeit ein. Er kann nur auf Sekunden genau sein und jede Einstellung kann nur einen Timer generieren. Die von der Funktion setitimer eingestellten Timer sind unterschiedlich. Sie können nicht nur (theoretisch) auf Mikrosekunden messen, sondern auch automatisch eine

Schleife

messen. In einem Unix-Prozess können Alarm- und ITIMER_REAL-Timer nicht gleichzeitig verwendet werden.

SIGINT Prozess beenden Prozess unterbrechen (Strg+C)SIGTERM Prozess beenden Software-Beendigungssignal

SIGKILL Prozess beenden Prozess beenden

SIGALRM Alarmsignal

Die Vorkenntnisse sind fast fertig, es ist Zeit, sich mit dem Signal von

Python

zu befassen.

Signalnamen definierenDas Signalpaket definiert jeden Signalnamen und seine entsprechende

Ganzzahl

, wie z. B.

den von Python verwendeten Signalnamen und Linux konsistent. Sie können die

voreingestellte Signalverarbeitungsfunktion über
import signal
print signal.SIGALRM
print signal.SIGCONT

$man 7 signal

abfragen. Der Kern des Signalpakets besteht darin, die Funktion signal.signal() zum Voreinstellen (Registrieren) zu verwenden ) Signalverarbeitungsfunktion, wie unten gezeigt:

signalnum ist ein bestimmtes Signal, und handler ist die Verarbeitungsfunktion des Signals. Wir haben in Signal Basics erwähnt, dass ein Prozess Signale ignorieren, Standardaktionen ausführen oder Aktionen anpassen kann. Wenn der Handler signal.SIG_IGN ist, wird das Signal ignoriert. Wenn der Handler singal.SIG_DFL ist, führt der Prozess die Standardaktion (Standard) aus. Wenn der Handler ein Funktionsname ist, führt der Prozess die in der Funktion definierte Aktion aus.

singnal.signal(signalnum, handler)
Im Hauptprogramm verwenden wir zunächst die Funktion signal.signal(), um die Signalverarbeitungsfunktion voreinzustellen. Dann führen wir signal.pause() aus, um den Prozess anzuhalten und auf das Signal zu warten. Wenn das Signal SIGUSR1 an den Prozess übergeben wird, wird der Prozess aus der Pause fortgesetzt und führt die SIGTSTP-Signalverarbeitungsfunktion myHandler() gemäß der Standardeinstellung aus. Einer der beiden Parameter von myHandler wird verwendet, um das Signal zu identifizieren (Signum), und der andere wird verwendet, um den Status des Prozessstapels (Stack-Frame) zu erhalten, wenn das Signal auftritt. Beide Parameter werden von der Funktion signal.singnal() übergeben.

上面的程序可以保存在一个文件中(比如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包被增强,信号阻塞等功能被加入到该包中。我们暂时不深入到该包中。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung, wie Python das Signalmodul verwendet, um geplante Ausführungsmethoden zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn