Let's just say what signal is. (If you want to use directly can not see)
Signal translation comes in Chinese is the signal--
Of course, in itself he is a very important concept in Linux system programming, signaling mechanism is a mechanism for passing messages between processes,
It's all called a soft interrupt signal.
The function is to notify the process that an asynchronous event has occurred. The process can call the system to pass the signal, and the kernel itself can send a signal to the process, telling the process that an event has occurred.
Note that the signal is only used to notify a process of what has happened and does not pass any data to the process.
The process of receiving signals has three processing methods for different signals.
- Specifying handler functions
- Ignore
- The default processing for most signals is to terminate the process according to the system default value
Then there is a big segment of the genre.
Linux systems have two major types of signals
- POSIX standard rule signal (regular signal 1-31 number)
- Real-time signal (real-time signal 32-63)
Rule signal
Signal Number |
name |
Default Action |
Description |
1 |
SIGHUP |
Terminate |
Terminating a control terminal or process |
2 |
SIGINT |
Terminate |
Terminal (CTRL-C) caused by the keyboard |
3 |
Sigquit |
Dump |
Controls the signal that the terminal sends to the process, the keyboard-generated exit (ctrl-\), |
4 |
Gigill |
Dusmp |
Illegal instruction caused |
5 |
SIGTRAP |
Dump |
Debug interrupt |
6 |
Sigabrt/sigiot |
Dump |
Exception abort |
7 |
Sigbus/sigemt |
Dump |
Bus exception/EMT Instructions |
8 |
SIGFPE |
Dump |
Floating-point Arithmetic overflow |
9 |
SIGKILL |
Terminate |
Forced kill process (big strokes, process not captured) |
10 |
SIGUSR1 |
Terminate |
User signals, processes can be customized for use |
11 |
SIGSEGV |
Dump |
Illegal memory address caused |
12 |
SIGUSR2 |
Terminate |
User signals, processes can be customized for use |
13 |
Sigpipe |
Terminate |
Write data to a pipe that is not read |
14 |
Sigalrm |
Terminate |
Clock interrupt (Alarm clock) |
15 |
SIGTERM |
Terminate |
Process termination (process can be captured) |
16 |
Sigstkflt |
Terminate |
Coprocessor Stack Error |
17 |
SIGCHLD |
Ignore |
Child process exits or interrupts |
18 |
Sigcont |
Go on |
Start running if process stop state |
19 |
SIGSTOP |
Stop it |
Stop a process from running |
20 |
Sigstp |
Stop it |
Keyboard-generated stop |
21st |
Sigttin |
Stop it |
Background process Request input |
22 |
Sigttou |
Stop it |
Background Process Request output |
23 |
Sigurg |
Ignore |
Socket Send Emergency case |
24 |
Sigxcpu |
Dump |
CPU time limit is broken |
25 |
Sigxfsz |
Dump |
File size limit is broken |
26 |
Sigvtalrm |
Terminate |
Virtual Timing Clock |
27 |
Sigprof |
Terminate |
Profile Timer Clock |
28 |
Sigwinch |
Ignore |
Window resizing |
29 |
Sigio/sigpoll |
Terminate |
I/O available |
30 |
Sigpwr |
Terminate |
Power supply exception |
31 |
Sigsys/sysunused |
Dump |
System Call exception |
Note: It is best to use the signal name because the same value corresponds to the same signal type in different systems.
The smaller the value of the signal, the higher the priority.
OK, now it's time to talk about processing in Python.
First, a few common signals are listed:
numbering |
Signal name |
Description |
2 |
SIGINT |
The process receives this signal when the keyboard (CTRL-C) key combination is pressed |
15 |
SIGTERM |
When the user enters the kill sigterm PID. The corresponding process will receive this signal. This signal process is capable of capturing and specifying function processing, such as doing a program cleanup. Even ignoring the signal. |
9 |
SIGKILL |
Forced kill process, this signal process can not be ignored, directly at the system level to kill the process. So in Python, he can't listen. |
14 |
Sigalrm |
Alarm Clock signal |
Go to yards
Let's start with an example.
#!/usr/bin/env python#-*-Coding:utf-8-*-"" "Listen to the SIGINT signal, when the program is running at the same time press the keyboard CTRL + C will be output to receive a signal 2 <frame object at 0x00000000021dd048> handler method of the two parameters respectively is Signal number, program frame "" "Import sysreload (SYS) sys.setdefaultencoding ("Utf-8")Import timeImport OSImport Signalreceive_times =0DefHandler(Signalnum, handler):global receive_times print u "received signal ", Signalnum, Frame, receive_times receive_times + = 1 if receive_ Times > 3:exit (0) # walk def main (): Signal.signal (signal. SIGINT, handler) # ctrl-c # Time.sleep (Ten) # SIGINT signal can also wake up Time.sleep, so here the program will end while true: # changed to a while effect would be better passif __name__ = = ' __main__ ': Main ()
Another look at SIGTERM
the effect
#!/usr/bin/env python#-*-Coding:utf-8-*-"" "When we run the program, it continues to run because while is True. This is the SIGTERM signal, so when we enter the kill PID at the terminal (the Linux kill defaults to send SIGTERM), the program outputs: the signal is received at the <frame object at 0x7ff6957380 50> 0 Force yourself to kill when it is over 3 times. So SIGTERM is a great place to do some clean-up work. ""Import sysreload (SYS) sys.setdefaultencoding ("Utf-8")Import timeImport OSImport Signalreceive_times =0Defhandler (Signalnum, frame): global Receive_times print u "received signal", signalnum, Frame, receive_times Receive_times + = 1 if receive_times > 3:exit (0) # walk def main (): print "pid:", Os.getpid () signal.signal (signal. SIGTERM, handler) while true: Passif __name__ = ' __main__ ': Main ()
Just now we said Sigkill can't be monitored.
# 这里系统会直接跑错 AttributeError: ‘module‘ object has no attribute ‘SIGKILL‘
Finally, an example of practical use
In the python2.x version, the thread has a bug that cannot receive a signal at join
See: https://bugs.python.org/issue1167930
So if we run the following code
#!/usr/bin/env python#-*-Coding:utf-8-*-"" Here we listen to the SIGINT signal, but when we press CTRL-C, the program does not have any output. Or wait for the thread to run the completion program before exiting. "" "Import sysreload (SYS) sys.setdefaultencoding ("Utf-8")Import timeImport OSImport SignalImport Threadingreceive_times =0DefHandler(Signalnum, frame):Global Receive_timesPrintU "Receive signal", Signalnum, Frame, receive_times receive_times + =1If Receive_times >3:# Os.kill (Os.getpid (), signal. SIGTERM) # I'm crazy to kill myself. Exit (0)DefRun():Print"Thread%s run:"% (Threading.currentthread (). GetName ()) Time.sleep (10)Print "thread%s done"% (Threading.currentthread (). GetName ()) def main (): print "pid:", Os.getpid () Signal.signal (signal. SIGINT, handler) thread_list = [] for i in range (5): Thread = Threading. Thread (target = run) thread_list.append (thread) for thread in Thread_list:thread.start () for thread in thread_list: Thread.Join () print "All Thread Done" if __name__ = ' __main__ ': Main ()
And then we'll change it.
#!/usr/bin/env python#-*-Coding:utf-8-*-"" "Here we discard the thread's join () method, then replace it with a while True, and then determine the thread's surviving state in the main process. This enables both a continuous running thread and the ability to interrupt "" at any time according to demandImport sysreload (SYS) sys.setdefaultencoding ("Utf-8")Import timeImport OSImport SignalImport Threadingis_run_thread =TrueDefHandler(Signalnum, frame):PrintU "Receive signal", Signalnum, FrameGlobal Is_run_thread Is_run_thread =False# Stop Running ThreadsDefRun():Print"Thread%s run:"% (Threading.currentthread (). GetName ())While Is_run_thread:# do somethingPassPrint"Thread%s Done"% (Threading.currentthread (). GetName ())DefMain():Print"pid:", Os.getpid () signal.signal (signal. SIGINT, handler) thread_list = []for i in range (5): thread = Threading. Thread (target = run) thread_list.append (thread) for thread in Thread_list:thread.start () # note here while true: for thread in thread_list: if thread.isalive (): break else: break # for thread in thread_list: # thread.join ( ) print "All thread Done" if __name_ _ = = ' __main__ ': Main ()
Note that only sigabrt, SIGFPE, sigill, SIGINT, SIGSEGV, or wnidows can be called in the system. SIGTERM
Python and Signal