A preliminary understanding of signal communication _python the Python process

Source: Internet
Author: User
Tags sigint signal

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 ' 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.