selfboot / AnnotatedShadowSocks

Annotated shadowsocks(python version)
Other
3 stars 1 forks source link

signal:Set handlers for asynchronous events #28

Open selfboot opened 7 years ago

selfboot commented 7 years ago

Signal

Signals are software interrupts. Most nontrivial application programs need to deal with signals. Signals provide a way of handling asynchronous events—for example, a user at a terminal typing the interrupt key to stop a program or the next program in a pipeline terminating prematurely.

First, every signal has a name. These names all begin with the three characters SIG. For example, SIGABRT is the abort signal that is generated when a process calls the abort function. SIGALRM is the alarm signal that is generated when the timer set by the alarm function goes off. Signals are identified by integers and are defined in the operating system C headers. Python exposes the signals appropriate for the platform as symbols in the signal module.

We can tell the kernel to do one of three things when a signal occurs. We call this the disposition of the signal, or the action associated with a signal.

  1. Ignore the signal.
  2. Catch the signal. To do this, we tell the kernel to call a function of ours whenever the signal occurs. In our function, we can do whatever we want to handle the condition.
  3. Let the default action apply. Every signal has a default action, note that the default action for most signals is to terminate the process.

Common signals we often see:

python signal module

The module signal provides mechanisms to use signal handlers in Python. Some general rules for working with signals and their handlers.

The variables defined in the signal module are: signal.SIG_DFL, signal.SIG_IGN, SIG*, signal.signal(signalnum, handler) and so on.

Demo

As with other forms of event-based programming, signals are received by establishing a callback function, called a signal handler, that is invoked when the signal occurs. The arguments to your signal handler are the signal number and the stack frame from the point in your program that was interrupted by the signal.

import signal
import time
import sys
import os

def handle_int(sig, frame):
    print "get signal: %s, I will quit"%sig
    sys.exit(0)

def handle_hup(sig, frame):
    print "get signal: %s"%sig

if __name__ == "__main__":
    signal.signal(2, handle_int)
    signal.signal(1, handle_hup)
    print "My pid is %s"%os.getpid()
    while True:
        time.sleep(3)

This relatively simple example script loops indefinitely, pausing for a few seconds each time. When a signal comes in, the sleep call is interrupted and the signal handle_int for signal 2 and handle_hup for signal 1) prints the signal number(default handle for the other signal). Here we can use command kill to send signal in other terminal. We use kill -HUP pid or kill -1 pid to send signal 1, and ctrl-c in the same terminal or kill -2 pid to send signal 2.

$ python demo.py
My pid is 74608
get signal: 1
get signal: 1
^Cget signal: 2, I will quit

Ref
Python进程间异步通信之signal模块
signal – Receive notification of asynchronous system events