This article mainly introduces the use of the signal package in Python, and mainly performs operations on process signals in Linux, if you want to execute a command every minute in the liunx system, the most common method is crontab. If you do not want to use crontab, after being instructed by my colleagues, I could use a timer in the program to implement this function. So I began to explore and found that I needed some signal knowledge...
Check what signals your linux supports: 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
(58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62)
63) SIGRTMAX-1 64) SIGRTMAX
Root @ server :~ #
Signal: Communication Between processes is a software interruption. Once a process receives a signal, it will interrupt the original program execution process to process the signal. The operating system specifies the default behavior after the process receives the signal. However, we can bind a signal processing function to modify the behavior after the process receives the signal, two signals are unchangeable: SIGTOP and SIGKILL.
There are two reasons for sending signals:
1 (passive) the kernel detects a system event. For example, if a sub-process exits, it will send a SIGCHLD signal like a parent process. Pressing control + c on the keyboard will send a SIGINT signal.
2 (active) sends signals to a specified process by calling kill.
There is a setitimer function in the C language. The setititimer function can provide three timers, which are independent of each other. Any timed completion will send a scheduled signal to the process and automatically re-timing. The which parameter determines the timer type:
ITIMER_REAL specifies the actual time, which is of the same type as alarm. SIGALRM
The actual execution time of the ITIMER_VIRT scheduled process in the user State. SIGVTALRM
The actual execution time of the ITIMER_PROF scheduled process in the user and core states. SIGPROF
The signals sent to the process are different when the timer is completed. The ITIMER_REAL class timer sends the SIGALRM signal, the ITIMER_VIRT class timer sends the SIGVTALRM signal, and the ITIMER_REAL class timer sends the SIGPROF signal.
The function alarm is essentially a low-precision, non-heavy ITIMER_REAL class timer. It can only be accurate to seconds, and each setting can only generate a timer. The timer set by the setitimer function is different. They can not only time the time to the subtle (theoretically), but also automatically cycle the time. In a Unix process, the alarm and ITIMER_REAL timers cannot be used at the same time.
SIGINT terminates the process to interrupt the process (control + c)
SIGTERM termination process software termination signal
SIGKILL terminate the process and kill the process
SIGALRM alarm signal
The preliminary knowledge is almost ready, and it is time to enter the signal of python.
Define signal name
The signal package defines each signal name and its corresponding integer, such
import signalprint signal.SIGALRMprint signal.SIGCONT
The signal used by Python is the same as that used by Linux. You can use
$man 7 signal
Query
Preset signal processing functions
The core of the signal package is to use the signal. signal () function to preset the (register) signal processing function, as shown below:
singnal.signal(signalnum, handler)
Signalnum is a signal, and handler is the processing function of the signal. As we mentioned in the signal base, processes can ignore signals, take default operations, and customize operations. When handler is signal. SIG_IGN, the signal is ignored (ignore ). When handler is singal. SIG_DFL, the process performs default operations ). When handler is a function name, the process takes the operation defined in the function.
import signal# Define signal handler functiondef myHandler(signum, frame): print('I received: ', signum)# register signal.SIGTSTP's handler signal.signal(signal.SIGTSTP, myHandler)signal.pause()print('End of Signal Demo')
In the main program, we first use the signal. signal () function to preset the signal processing function. Then we execute signal. pause () to pause the process and wait for the signal. When the signal SIGUSR1 is passed to the process, the process is restored from the pause, and the signal processing function myHandler () of SIGTSTP is executed according to the preset (). One of the two parameters of myHandler is used to identify the signal (signum), and the other is used to obtain the status of the process stack when the signal occurs (stack frame ). Both parameters are passed by the signal. singnal () function.
The above program can be saved in a file (such as test. py ). Run the command as follows:
$python test.py
To run the process. When the program runs to signal. pause (), the process is paused and waits for a signal. Press CTRL + Z to send the SIGTSTP signal to the process. We can see that the process executes the myHandle () function, then returns to the main program, and continues to execute. (Of course, you can also use $ ps to query the process ID and then use $ kill to send a signal .)
(The process does not have to use signal. pause () pause to wait for the signal. It can also accept the signal during work, such as replacing the above signal. change pause () to a cycle that requires a long period of work .)
We can modify the operations in myHandler () as needed to achieve personalized processing for different signals.
Timed SIGALRM Signal
A useful function is signal. alarm (), which is used to send a SIGALRM signal to the process itself after a certain period of time:
import signal# Define signal handler functiondef 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')
Here we use an infinite loop to make the process run continuously. After signal. alarm () is executed for 5 seconds, the process sends a SIGALRM signal to itself. Then, the signal processing function myHandler starts to execute.
Send signal
The core of the signal package is to set the signal processing function. In addition to signal. alarm (), it does not provide other signal sending functions. However, in the OS package, there are functions similar to the linux kill command, which are
os.kill(pid, sid)os.killpg(pgid, sid)
Send signals to processes and Process Groups (see Linux Process relationship) respectively. Sid is the integer or singal. SIG * corresponding to the signal *.
In fact, signal, pause, kill, and alarm are common C library functions in Linux application programming. Here, we just implement them in Python. In fact, Python interpreters are written in C language, so this similarity is not surprising. In addition, in Python 3.4, functions such as signal package enhancement and signal blocking are added to this package. We will not go into this package for the time being.