Signal in Python

Tram Ho

Signal

UNIX / Linux systems provide special mechanisms to communicate between processes. One of them is called signals.

In short, a signal is like a notification of an event. When an event occurs in the system, a signal will be generated to notify other programs about this event.

A simple example: When you are running a command in the terminal. The command is running, but you use ctrl + C At that time, a signal called SIGINT was generated. And the terminal will read that signal and execute the stop command.

On UNIX-based systems, there are three main types of signals:

  • System signals:
    • SIGILL
    • SIGTRAP
    • SIGBUS
    • SIGFPE,
    • SIGKILL
    • SIGSEGV
    • SIGXCPU
    • SIGXFSZ
    • SIGIO
  • Device signals:
    • SIGHUP
    • SIGINT
    • SIGPIPE
    • SIGALRM
    • SIGCHLD
    • SIGCONT
    • SIGSTOP
    • SIGTTIN
    • SIGTTOU
    • SIGURG
    • SIGWINCH
    • SIGIO
  • User-defined signals:
    • SIGQUIT
    • SIGABRT
    • SIGUSR1
    • SIGUSR2
    • SIGTERM

Each signal will be represented by an integer value.

On Ubuntu, you can check this signal list:

When you execute the man 7 signal command, you will also see how to use the signal in Ubuntu:

Python signal

Since Python 1.4, the signal library has been integrated and updated regularly into the core.

Python Basic

A small example of using the SIGINT signal:

Lines 1, 2 will import lib signal and lib time .

Line 5, 6 define function handle signal. In this function, I will print the integer value of the signal and frame it receives along with the signal.

Line 8 uses the signal.signal() function to assign handle SIGINT signal. Every time the CPU receives ctrl + c , the function handler is executed.

Lines 10, 11, 12 use while True to keep the program running.

Save the above code to test it:

The above is a very simple example of using sinal in Python basic.

Django

Django provides signal dispatcher . It allows separate apps to be notified when actions take place elsewhere in the framework.

Signal built-in in Django:

  • django.db.models.signals.pre_save & django.db.models.signals.post_save : Send before or after the save () method is executed in the model.
  • django.db.models.signals.pre_delete & django.db.models.signals.post_delete : Send before or after the delete () method is implemented in the model.
  • django.db.models.signals.m2m_changed : Sent when ManyToManyField on a model is changed.
  • django.core.signals.request_started & django.core.signals.request_finished : Sent when Django starts or finishes an HTTP request.

In django, use the Signal.connect() method to register a receiver function. receiver function is called when a signal is sent. All signal’s receiver functions are called at the same time and based on the order of registration.

The problem below is printing out the words Request finished! on the console after each request is completed.

Receiver functions

First, how is the receiver defined?

Note, the receiver function must have sender argument. Other arguments will need to be pushed into **kwargs .

Connecting receiver functions

There are 2 syntaxes that allow connect a receiver to a signal.

  • Option1: use request_finished.connect() .

  • Option2: use receiver() decorator.

After setup is complete, the my_callback function will be called every time the request finishes.

With the above problem, all the requests will end up firing a signal. So with the problem, I will only shoot signal with a specific case, why?

Connecting to signals sent by specific senders

In user registration problem. Suppose you have a User model. After saving the user info to the model, I want to send a notification that “You have successfully registered” for example.

I will need to use signal built-in: from django.db.models.signals import post_save

Summary

In this article, I showed you what a signal is? How to use signal in Python in general and in Django in particular.

Thanks for reading!

Share the news now

Source : Viblo