Ctrl c signal python

Capturing and Handling OS signals like SIGINT (CTRL-C) in Python

we will learn how to capture and handle operating system signals like SIGINT and SIGBREAK on Linux and Windows OS’s to control the flow of your python script during execution . We will use the signal module from Python 3 to capture and handle the OS signals.

The tutorial will teach the user to write your own custom signal handler to catch OS signals like SIGINT (CTRL +C ),SIGBREAK (CTRL+BREAK),

How to register the signal with your custom signal handler and override the default signal behavior.

We will then use the SIGINT ,SIGBREAK to exit from an infinite loop in Python while closing our open resources like file objects, Serial connections etc in an orderly manner on Linux and Windows systems.

In the below example we have an infinite loop constantly doing something in the following manner,

Now we want to stop our script from what it was doing and exit gracefully while closing all the opened resources like Serial port object or File object. This where we can use the OS signal to interrupt the execution of our infinite loop.

Some IDE’s like Thonny, IDLE etc may interfere with the capture of signals like SIGINT(CTRL+C) or SIGBREAK.

If you are having issues with the signal not triggering your handler function try running the code directly on the command line outside the IDE as shown below.

D:\> python your_signal_handling_code.py 
$python3 your_signal_handling_code.py 

Source codes

Website code may be partial or pseudo code just enough to highlight relevant techniques or methods.

Please use the full source codes from our Github Repo to avoid errors

What are Signals

Signal is a way in which a program or process (here our python script) can receive information from the Operating System that certain events like a Keyboard Press (CTRL + C ) or a Fault have happened.

Signals are assigned a Integer Value by the OS.

operating system signal SIGINT handling tutorial in python 3

When we press CTRL + C on our Keyboard the Operating System (Both Windows and Linux) will generate a SIGINT signal which is send to the program which is currently active.

The receiving Program can either execute the default function specified by the SIGINT signal

or It can use a signal handler to trap the SIGINT signal and execute a custom user specified function.

Not all signals are available on all systems. Signals differ between operating systems(Linux/Windows)

Читайте также:  Postgresql java stored procedures

Checking for available signals in your OS.

Since not all signals are available in every OS, It is good to know which ones are available on your system.

Here we will be using Python 3 (Python 3.9.x) and to access the signals we have to import the signal module

import signal # Import signal module # available signals on our System valid_signals = signal.valid_signals() # requires python 3.9.0 # returns a SET print('Number of Available Signals ->', len(valid_signals) , '\n') for i in valid_signals: print(i)

The above partial code will print available signals on a particular OS. Download the full codes from Github

valid_signals = signal.valid_signals()

returns a set of available OS specific signals which are then printed out.

Available OS Signals on Windows 10

python OS Signal handling on Windows System

Available OS Signals on Linux

displaying available signals on Linux using python signal.valid_signal() function

As you can see from the above images, there are significant differences in the number and types of Signals available in Linux and Windows systems.

Programming Signals on Python 3

To use the Signal received by our script we have to do two things

  1. Write a Signal Handler which will do the custom processing ,when Signal is received
  2. Register the Signal with the Signal Handler function
import signal def your_custom_signal_handler(signal_number,frame): code to do something code to do something code to do something signal.signal(signal.SIGNALNAME,your_custom_signal_handler)

how to configure a signal handler for SIGINT (CTRL+C) or SIGBREAK signal using python signal module in windows and linux

Here we will be using the SIGINT signal to control the execution of our Python 3 script.

SIGINT Signal is common to both Windows and Linux systems and helps us to run our code on both Windows and Linux Systems.

Please use the code from Github

import signal # Import signal module def SignalHandler_SIGINT(SignalNumber,Frame): print('SignalHandler of signal.SIGINT') #register the signal with Signal handler signal.signal(signal.SIGINT,SignalHandler_SIGINT) while 1:  print("Press Ctrl + C ") time.sleep(1) 
def SignalHandler_SIGINT(SignalNumber,Frame):

is the Signal Handler , So when the Signal SIGINT is generated this function is called and the print() statement under is called.

signal.signal(signal.SIGINT,SignalHandler_SIGINT)

registers the signal handler function SignalHandler_SIGINT (SignalNumber,Frame): with the signal SIGINT signal.SIGINT

Working of Python SIGINT Signal Code

If you run the above code ,

  1. The Python script will print «Press CTRL + C» in an infinite loop,
  2. When you hit CTRL +C on the Keyboard , A SIGINT signal is generated by the OS (Windows/Linux) and send to the executing script.
  3. The Python script then transfer the control to the Signal Handler inside our script def SignalHandler_SIGINT (SignalNumber,Frame): and then executes the print statement under it «SignalHandler of signal.SIGINT»
  4. After which the control will transfer back to the infinite loop
Читайте также:  Python and machine learning pdf

Please note that the code should be run under the command line.

catching and using SIGINT signal on windows using Python signal module

If you use an IDE like Thonny or IDLE, the IDE tend to interfere with the reception of the SIGINT signal

Safely Exiting from an infinite loop in Python

In this example we will learn how to safely exit from an infinite loop in Python 3 using signals.

In some application like Serial Port Data Acquisition System Software written in Python we have to query a sensor or Microcontroller like Arduino or Raspberry Pi board continuously in a infinite loop.

In those applications we can use the SIGINT signal (CTRL +C) to interrupt the infinite loop and close the application safely without a resource leak.

You can also use a SIGBREAK (CTRL + BREAK ) signal to do so but the signal is only available in Windows while SIGINT is available on both Linux and Windows.

import signal import time Sentry = True # Create a Signal Handler for Signals.SIGINT: CTRL + C def SignalHandler_SIGINT(SignalNumber,Frame): global Sentry  Sentry = False signal.signal(signal.SIGINT,SignalHandler_SIGINT) while Sentry: #exit loop when Sentry = False print('Long continous event Eg,Read from sensor') time.sleep(1) print('Out of the while loop') print('Clean up code Here')
  1. Now in the above code we are using a Sentry Variable to control the flow of the while loop at the bottom
  2. The Sentry Variable is set as True, Sentry = True when the script runs first and the while loop runs continuously.
  3. When the user wants to stop the loop ,he can generate the SIGINT signal by pressing CTRL + C .
  4. The SIGINT signal handler will run and set the Sentry Variable to False .
  5. The control then passes to the While loop where Sentry == False will result in loop terminating and control getting passed to print() statements below.
  6. User can do the cleanup there

Sentry have to defined as Global, inside the signal handler

global Sentry

Sentry = False

Getting out of the infinite loop in Python on Windows

exiting from a infinite loop in python using SIGINT signal on Windows

Getting out of the infinite loop in Python on Linux using SIGINT

Источник

Модуль signal в Python

В этой статье мы рассмотрим использование модуля Python signal. Этот модуль очень полезен, когда мы хотим обрабатывать определенные сигналы с помощью Python.

Python Signal модуль

Что такое сигнал?

Сигнал — это средство, с помощью которого программа может получать информацию от операционной системы. Когда операционная система получает определенные события, она может передать их программам в виде сигналов.

Например, когда мы нажимаем клавиши Ctrl + C на клавиатуре, операционная система генерирует сигнал и передает его программам. Для этой конкретной комбинации генерируется сигнал SIGINT и передается в программы.

Читайте также:  METANIT.COM

Для всех распространенных операционных систем существует стандартный шаблон для назначения этих сигналов, которые обычно являются сокращением от целых чисел.

В Python эти сигналы определены в модуле signal .

Чтобы просмотреть все допустимые сигналы в вашей системе (в зависимости от ОС), вы можете использовать signals.valid_signals()

import signal valid_signals = signals.valid_signals() print(valid_signals)
, , , , , , , , , , , , , , , 16, , , , , , , , , , , , , , , , , 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, >

Теперь для всех сигналов есть некоторые действия по умолчанию, которые ОС назначит каждой программе. Если вместо этого мы хотим иметь другое поведение, мы можем использовать обработчики сигналов.

Что такое обработчик сигналов в Python?

Обработчик сигналов в Python — это определяемая пользователем функция, с помощью которой можно обрабатывать сигналы Python.

Если мы возьмем сигнал SIGINT (сигнал прерывания), поведение по умолчанию будет заключаться в остановке текущей запущенной программы.

Однако мы можем назначить обработчик сигнала для обнаружения этого сигнала и вместо этого выполнять нашу собственную обработку.

Давайте посмотрим, как это сделать.

import signal import time # Our signal handler def signal_handler(signum, frame): print("Signal Number:", signum, " Frame: ", frame) def exit_handler(signum, frame): print('Exiting. ') exit(0) # Register our signal handler with `SIGINT`(CTRL + C) signal.signal(signal.SIGINT, signal_handler) # Register the exit handler with `SIGTSTP` (Ctrl + Z) signal.signal(signal.SIGTSTP, exit_handler) # While Loop while 1: print("Press Ctrl + C") time.sleep(3)

После того, как мы запустим нашу программу, когда мы нажмем Ctrl + C, программа перейдет к функции signal_handler() , поскольку мы зарегистрировали обработчик с помощью SIGINT (Ctrl + C).

У нас также есть другой обработчик exit_handler() который выходит из программы, если мы нажимаем Ctrl + Z, который отправляет сигнал SIGTSTP .

Press Ctrl + C ^CSignal Number: 2 Frame: > ^ZExiting.

Здесь я нажал Ctrl + C, чтобы перейти к функции signal_handler() , а затем нажал Ctrl + Z, чтобы выйти из программы.

Обратите внимание, что есть объект frame стека ( frame ) для отслеживания стека выполнения основной программы.

Использование SIGALARM

Мы можем использовать сигнал SIGALARM для отправки сигналов тревоги нашей программе. Напишем простой обработчик сигнала.

import signal import time def alarm_handler(signum, frame): print('Alarm at:', time.ctime()) # Register the alarm signal with our handler signal.signal(signal.SIGALRM, alarm_handler) signal.alarm(3) # Set the alarm after 3 seconds print('Current time:', time.ctime()) time.sleep(6) # Make a sufficient delay for the alarm to happen

В последней строке мы ждем в течение достаточного времени (6 секунд), чтобы сигнал тревоги прошел в нашу программу. В противном случае, поскольку программа завершилась бы, сигнал не будет получен.

Current time: Thu Jul 23 00:41:40 2020 Alarm at: Thu Jul 23 00:41:43 2020

Источник

Оцените статью