The concept of the signal
Signal (signal)--the way communication between processes is a software outage. Once a process receives a signal, it interrupts the original program execution process to process the signal.
Several common signals:
SIGINT Terminate process interrupt process (CONTROL+C)
Sigterm terminate 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 more friendly, the process can capture this signal and close 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 generally two reasons for sending a signal:
The 1 (passive) kernel detected a system event. For example, a child process exit will send a SIGCHLD signal like a parent process. The keyboard presses CONTROL+C sends the SIGINT signal.
2 (Active) sends a signal to the specified process through system call kill
the signal 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 SIGRTMAX-1)
The signal that Python provides
Python 2.4.3 (#1, June 2009, 14:09:58)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)]
on linux2 Type ' help ', "copyright "," credits "or" license "for the more information.
>>> Import Signal
>>> dir (signal)
[' Nsig ', ' sigabrt ', ' sigalrm ', ' sigbus ', ' sigchld ', ' Sigcld ', ' sigcont ', ' sigfpe ', ' sighup ', ' Sigill ', ' SIGINT ', ' Sigio ', ' Sigiot ', ' SIGKILL ', ' sigpipe ', ' sigpoll ', ' sigprof ' , ' SIGPWR ', ' sigquit ', ' Sigrtmax ', ' sigrtmin ', ' SIGSEGV ', ' SIGSTOP ', ' sigsys ', ' sigterm ', ' sigtrap ', ' sigtstp ', ' 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 prescribes the default behavior after the process receives a signal
However, we can modify the behavior of the process after receiving the signal by binding the signal processing function.
There are two signals that are not sigtop and Sigkill
binding signal Processing functions
Import OS
import signal
from time import sleep
def onsignal_term (a,b):
print ' Receive Sigterm signal '
# Here is the binding signal processing function that binds the sigterm to the function onsignal_term above
signal.signal (signal. Sigterm,onsignal_term
def ONSIGNAL_USR1 (a,b):
print ' receives SIGUSR1 signal '
#这里是绑定信号处理函数, Bind the SIGUSR1 to the onsignal_term above the function
signal.signal (signal. SIGUSR1,ONSIGNAL_USR1)
while 1:
print ' My process id is ', os.getpid () Sleep
(10)
Run the program. It then sends a signal through another process.
Send a signal
The code to send the signal is as follows:
Import OS
import signal
#发送信号, 16175 is the previous binding signal processing function PID, need to modify
Os.kill (16175,signal. Sigterm)
#发送信号, 16175 is the previous binding signal processing function of the PID, you need to modify
Os.kill (16175,signal. SIGUSR1)
SIGCHLD Signal
It then shows an example of automatically sending a SIGCHLD signal to the parent process at the end of a subprocess.
"" "" "
the end of the subprocess sends the SIGCHLD signal to the parent process
'
import OS import signal from time
import sleep
def ONSIGCHLD (a,b):
print ' receives child process end Signal '
signal.signal (signal. SIGCHLD,ONSIGCHLD)
pid = os.fork ()
if pid = = 0:
print ' I am a subprocess, PID is ', Os.getpid () Sleep
(2)
Else :
print ' I am the parent process, PID is ', Os.getpid ()
os.wait () #等待子进程结束
Where to use a signal requires special attention:
If a process receives a SIGUSR1 signal and then performs a signal binding function, the second SIGUSR2 signal is returned, the first signal is not processed, and the second signal is discarded.
So try not to use the signal in multiple threads.
The test didn't find any signal loss.
Example Demo:
To receive the signal, you will find that if there is another end using multithreading to send signals to the process, some signals will be omitted.
Import OS
import signal from time
import sleep
import Queue
qcount = Queue.queue () #初始化队列
def ONSIGCHLD (a,b):
' after receiving the signal, insert a number 1 ' print ' in 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 process while
1:
print ' My PID is ', Os.getpid ()
print ' Now the number of elements in the queue is ', Qcount.qsize () Sleep
(2)
Multithreading Signal-side program:
' '
use multithreading to send a signal to another process '
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
-worker:
I.start () for I-in
worker :
i.join ()
print ' main thread complete '
Content supplement:
Alarms is a special signal type that allows the program to require the system to send notifications to itself 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 in the following example, the original program to sleep 10 before printing out print ' After: ', Time.ctime (), but because of Signal.alarm (2), so 2 seconds after the execution of the printing.
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 (a)
print ' after: ', Time.ctime ()
Note that signal only the main thread can receive the signal, as in the following example, the print ' done waiting ' statement is not printed, and if Signal.alarm (2) is not invoked, the program will always block
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 (s Ignal.
SIGUSR1, Signal_handler) def wait_for_signal (): print ' Waiting for signal in ', Threading.currentthread (). Name Signal.pause () print ' Done waiting ' # Start a thread that'll not receive the signal receiver = Threa Ding. Thread (target=wait_for_signal, name= ' receiver ') Receiver.start () Time.sleep (0.1) def send_signal (): Prin T ' 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 the Signa
L (not going to happen!) print ' Waiting for ', Receiver.name signal.alarm (2) receiver.join ()
It is also important to note that although the alarms class signal can be invoked on any thread, it can only be received in the main thread, as in the following example, even though the use_alarm call Signal.alarm (1), 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'll 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 the signal (not going to happen!)
Print time.ctime (), ' Waiting for ', Alarm_thread.name
alarm_thread.join ()
print time.ctime (), ' exiting Normally '