the concept of a signal
Signal (signal)--the way communication between processes is a software interrupt. Once a process receives a signal, it interrupts the original program execution process to process the signal.
Several common signals:
SIGINT terminating process interrupt process (CONTROL+C)
SIGTERM terminating process software termination signal
SIGKILL Terminate process Kill process
SIGALRM Alarm Clock signal
The difference between the process end signal sigterm and Sigkill
Sigterm is friendly and the process captures the signal and shuts down the program according to your needs. Before you close the program, you can end the open record file and complete the task you are doing. In some cases, if the process is working and cannot be interrupted, the process can ignore the sigterm signal.
For Sigkill signals, the process cannot be ignored. This is a "I don't care what you are doing, stop immediately" signal. If you send a sigkill signal to the process, Linux stops the process there.
There are two general reasons for sending a signal:
1 (passive) The kernel detects a system event. For example, a child process exit sends a SIGCHLD signal like a parent process. Keyboard presses CONTROL+C sends SIGINT signal
2 (Active) sends a signal to the specified process via system call Kill
Signals provided by the Linux operating system
[100003@oss235 myppt]$ Kill-l
1) SIGHUP 2) SIGINT 3) Sigquit 4) Sigill
5) SIGTRAP 6) SIGABRT 7) Sigbus 8) SIGFPE
9) SIGKILL) SIGUSR1 SIGSEGV) SIGUSR2
Sigpipe) sigalrm SIGTERM) Sigstkflt
SIGCHLD) Sigcont SIGSTOP) SIGTSTP
) (Sigttin) Sigttou () Sigurg) sigxcpu
SIGXFSZ) sigvtalrm sigprof) sigwinch
SIGIO) SIGPWR Sigsys) sigrtmin
(sigrtmin+1) (sigrtmin+2) sigrtmin+3) sigrtmin+4
sigrtmin+5) sigrtmin+6 sigrtmin+7) sigrtmin+8
sigrtmin+9) (sigrtmin+10) sigrtmin+11) sigrtmin+12
sigrtmin+13) (sigrtmin+14) sigrtmin+15) SIGRTMAX-14
SIGRTMAX-13) SIGRTMAX-12-SIGRTMAX-11) SIGRTMAX-10
SIGRTMAX-9) SIGRTMAX-8 () SIGRTMAX-7) SIGRTMAX-6
SIGRTMAX-5) SIGRTMAX-4 () SIGRTMAX-3) SIGRTMAX-2
SIGRTMAX-1) Sigrtmax
Signals provided by Python
Python 2.4.3 (#1, June, 14:09:58) [GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on Linux2type ' help ', ' copyright ', ' credit S "or" license "for more information.>>> import signal>>> dir (signal) [' NSIG ', ' sigabrt ', ' sigalrm ', ' SI Gbus ', ' SIGCHLD ', ' sigcld ', ' sigcont ', ' SIGFPE ', ' SIGHUP ', ' Sigill ', ' SIGINT ', ' SIGIO ', ' Sigiot ', ' SIGKILL ', ' sigpipe ', ' S Igpoll ', ' sigprof ', ' sigpwr ', ' sigquit ', ' Sigrtmax ', ' sigrtmin ', ' SIGSEGV ', ' SIGSTOP ', ' sigsys ', ' SIGTERM ', ' SIGTRAP ', ' S IGTSTP ', ' sigttin ', ' Sigttou ', ' Sigurg ', ' SIGUSR1 ', ' SIGUSR2 ', ' sigvtalrm ', ' sigwinch ', ' sigxcpu ', ' sigxfsz ', ' SIG_DFL ', ' Sig_ign ', ' __doc__ ', ' __name__ ', ' alarm ', ' default_int_handler ', ' getsignal ', ' pause ', ' signal ']
The operating system specifies the default behavior after a process receives a signal
However, we can modify the behavior of the process after it receives the signal by binding the signal handler function.
There are two signals that are immutable sigtop and Sigkill
Binding Signal Processing functions
Import OS import signal from time import Sleep def onsignal_term (A, b): print ' received Sigterm signal ' # Here is the binding signal processing function, which binds sigterm to the function onsignal_term above signal.signal (signal. Sigterm,onsignal_term) def ONSIGNAL_USR1 (A, b): print ' received SIGUSR1 signal ' #这里是绑定信号处理函数, Bind the SIGUSR1 to the function onsignal_term above signal.signal (signal. SIGUSR1,ONSIGNAL_USR1) while 1: print ' My process id is ', os.getpid () sleep (10)
Run the program. The signal is then sent through another process.
Send Signal
The code to send the signal is as follows:
Import OS import signal #发送信号, 16175 is the PID of the previous binding signal processing function, need to modify Os.kill (16175,signal. SIGTERM) #发送信号, 16175 is the PID of the previous binding signal processing function, and needs to modify the Os.kill (16175,signal) itself. SIGUSR1)
SIGCHLD Signal
It then shows an example of automatically sending a SIGCHLD signal to the parent process after a child process has ended.
"'" ' end of child process sends SIGCHLD signal to Parent process "' import OS import signal from time import sleep def ONSIGCHLD (A, b): print ' receives the child process end Signal ' signal.signal (signal. SIGCHLD,ONSIGCHLD) pid = os.fork () if pid = = 0: print ' I am a child process, PID is ', Os.getpid () sleep (2) Else : print ' I am the parent process, PID is ', Os.getpid () os.wait () #等待子进程结束
Where to use the signal requires special attention:
If a process receives a SIGUSR1 signal and then executes the signal binding function, the second SIGUSR2 signal comes again and the first signal is not processed, the second signal is discarded.
Therefore, try not to use the signal in multi-threading.
This is inappropriate, the test didn't find a signal lost.
Example Demo:
The program that receives the signal, you will find that if there is another end using multithreading to send signals to this process, some signals will be omitted.
Import OS import signal from time import sleep import Queue qcount = Queue.queue () #初始化队列 def ONSIGCHLD (A, A, b): "" " after receiving a signal, insert a number 1" "Print" to the queue to receive the SIGUSR1 signal ' sleep (2) qcount.put (1) #向队列中写入 def exithanddle (s,e): raise Systemexit (' Receive terminate command, exit Program ') signal.signal (signal. SIGUSR1,ONSIGCHLD) #绑定信号处理函数 signal.signal (signal. Sigint,exithanddle) #当按下Ctrl + C terminate the process while 1: print ' My PID is ', Os.getpid () print ' Now the number of elements in the queue is ', Qcount.qsize ()
Multi-threaded signaling end of the program:
"'" " send a signal to another process using multithreading " ' import threading import OS import signal def SENDUSR1 (): print ' Send signal ' #这里的进程id需要写前一个程序实际运行的pid os.kill (17788, signal. SIGUSR1) WORKER = [] #开启6个线程 for I in range (1, 7): threadinstance = Threading. Thread (target = SENDUSR1) worker.append (threadinstance) for I in Workers : I.start () for I in worker : i.join () print ' main thread complete '
Content supplement:
Alarms is a special type of signal that allows a program to require the system to send itself a notification over a period of time. The OS standard module indicates that it can be used to avoid unrestricted blocking I/O operations or other system calls.
As the following example, the original program to print after sleep 10 after: ', Time.ctime (), but because Signal.alarm (2), so 2 seconds after the print.
Import signal import time def receive_alarm (Signum, stack): print ' alarm: ', Time.ctime () # Call Receive_alarm in 2 seconds signal.signal (signal. SIGALRM, Receive_alarm) signal.alarm (2) print ' Before: ', Time.ctime () time.sleep () print ' after: ', Time.ctime ()
Note that signal only the main thread to receive the signal, like the following example, the print ' done waiting ' statement cannot be printed, and if Signal.alarm (2) is not called, the program will block forever
Import signal Import threading import OS import time def signal_handler (num, stack): print ' Received signal%d in%s '% \ (num, Threading.currentthread (). Name) signal.signal (signal. SIGUSR1, Signal_handler) def wait_for_signal (): print ' Waiting for signal in ', Threading.currentthread (). Name signal.pause () print ' Done waiting ' # Start a thread that would not receive the signal receiver = thre Ading. Thread (target=wait_for_signal, name= ' receiver ') Receiver.start () Time.sleep (0.1) def send_signal ( ): print ' sending signal in ', Threading.currentthread (). Name Os.kill (os.getpid (), signal. SIGUSR1) sender = Threading. Thread (target=send_signal, name= ' sender ') Sender.start () sender.join () # Wait for the thread to see the Signal (not going to happen!) print ' Waiting for ', Receiver.name signal.alarm (2)
It is also important to note that although the alarms class signal can be invoked in any thread, it can only be received in the primary thread, such as the following example, even if the child thread Use_alarm calls Signal.alarm (1), but it does not work:
Import signal Import time import threading def signal_handler (num, stack): print time.ctime (), ' Alarm In ', Threading.currentthread (). Name signal.signal (signal. SIGALRM, Signal_handler) def use_alarm (): t_name = Threading.currentthread (). Name print time.ctime (), ' Setting alarm in ', T_name signal.alarm (1) print time.ctime (), ' Sleeping in ', T_name time.sleep (3) Print time.ctime (), ' Done with sleep in ', T_name # Start A thread that would not receive the signal Alarm_thread = Threading. Thread (target=use_alarm, name= ' Alarm_thread ') Alarm_thread.start () Time.sleep (0.1) # Wait For the thread to see the signal (not going to happen!) Print time.ctime (), ' Waiting for ', Alarm_thread.name alarm_thread.join ()