News
22nd July 2015 | By:

Unix SIGNALS

This is a small tutorial about signals in general, more precisely what they are designed for, how they work and handling of the signals.

Signals have various use cases but before we start exploring let’s see what a signal really is. At basic level a signal is an event/interrupt delivered by the operating system to your program, even if your program is busy doing something the signal will still be delivered, hence the interrupt part. Handling signals is done by setting up signal handler, this is just a normal function which will capture that signal and perform certain task, you can also ignore a given signal if you wish to.

It is important to note that not all signals are available for you to handle, there are two signals which cannot be catched: SIGKILL and SIGSTOP.

Example of Basic signal handling

The following code will setup a signal handler for SIGUSR1 and continously raise that signal. You can also send the signal to the program with the kill -SIGUSR1 command.

#include <stdio.h>
#include <signal.h>
#include <unistd.h> // for sleep()

void sig_handler(int signo)
{
	printf("got signal\r\n");
}

int main()
{
	if (signal(SIGUSR1, sig_handler) == SIG_ERR)
	{
		printf("signal() failed\r\n");
		return 1;
	}

	for(;;)
	{
		printf("Just working...\r\n");
		sleep(1);
		raise(SIGUSR1);
	}
}

List of available signals

There are many signals available and it is important to note that each signal has it’s own default handler, if you do not handle the signal in most cases the default action is to terminate your program. You can find the list of the signals with their description and default handlers at https://en.wikipedia.org/wiki/Unix_signal#POSIX_signals.

Interprocess communication

Signals are also a great way to communicate with processes hence allowing interprocess communication. You can easily spawn a new process and control that process by sending different signals to it, there are two general signals which can be used for exactly this purpose, SIGUSR1 and SIGUSR2, these signals are designed specifically to indicate a user defined conditions.

Unfortunately it is not really possible to pass in arbitrary data but what you can do is to use global variables when sending specific signals.

Signals are thread safe and can be interrupted by another signal, this opens the door to race conditions and you should be very careful when performing actions in your signal handler.

Timers and Alarms

Signals can also be used to create timers/alarms, here is full example which implements a simple timer of 5 seconds.

#include <stdio.h>
#include <signal.h>
#include <unistd.h> // for sleep()

void sig_handler(int signo)
{
	printf("timeout\r\n");
}

int main()
{
	if (signal(SIGALRM, sig_handler) == SIG_ERR)
	{
		printf("signal() failed\r\n");
		return 1;
	}

	/* setup 5 seconds timer. */
	alarm(5);
	for(;;)
	{
		printf("Just working...\r\n");
		sleep(1);
	}
}

References:
https://en.wikipedia.org/wiki/Unix_signal
http://lxr.free-electrons.com/source/include/linux/signal.h

Tags: , , , ,

Leave a reply

Your email address will not be published. Not now, not ever. Required fields are marked *

Comments


You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Name
Email
Website