How to Send Value Between Processes Using Signal -(Part 24/38)

In this project the Raspberrypi board is loaded with Ubuntu and is remotely accessed using VNC by attaching the Raspberrypi board through a LAN cable at the Ethernet port of the PC. The coding is done from the command line using the ‘vim’ editor and is compiled using ‘cc’ compiler.

A signal is a software interrupt that can be sent to a process which is currently executing in the Operating System. Most of the time the Operating system send signals to the processes, but process can also send signals to each other. Much like hardware interrupts it is a mechanism to notify a process that an event has occurred. Different signals are available which can be used to notify different events and these signals are differentiated by their signal numbers. The list of all the available signals in the OS and their signal numbers can be obtained using the following command:

kill -l

The following table gives a list of the most common signals that a process might encounter in an Operating System:

NAME

NUMBER

DESCRIPTION

SIGHUP

1

Linux sends a process this signal when it becomes disconnected from a terminal.

SIGINT

2

Linux sends a process this signal when the user tries to end it by

pressing CTRL+C.

SIGILL

4

Linux sends a process this signal when it attempts to execute an illegal instruction.

SIGABRT

6

Linux sends a process this signal to the process when the process calls the ‘abort ()’ function

SIGFPE

8

Linux sends a process this signal when it has executed an invalid floating-point math instruction

SIGKILL

9

Linux sends a process this signal to end it immediately

SIGUSR1

10

User programs can send this signal to other process

SIGUSR2

12

User programs can send this signal to other process

SIGSEGV

11

Linux sends a process this signal when the program has attempted an invalid memory access

SIGPIPE

13

Linux sends a process this signal when the program has attempted to access a broken data stream, such as a socket connection that has been already closed

SIGALRM

14

A process can receive this signal from the Linux using the function alarm (), after a time period mentioned in its argument.

SIGTERM

15

Linux sends a process this signal requesting it to terminate

SIGCHLD

17

Linux sends a process this signal when a child process exits

SIGXCPU

24

Linux sends a process this signal when it exceeds the limit of

CPU time that it can consume.

SIGVTALRM

26

A process can receive this signal from the Linux using the function setitimer (), after a time period mentioned in its argument.

Fig. 2: Common Signals For Sending Values Between Process In Operating System

The user programs should always try to use only the signals which are reserved for them, SIGUSR1 and SIGUSR2 to communicate between the processes. The steps which a process performs corresponding to a received signal are called ‘Signal Handling’. There should be a function called ‘Signal Handler’ inside the process which can perform the necessary things in response to a signal received.

Incase to get values or messages that are send along with the signals the function ‘sigaction ()’ can be used other than signal () defined in the header file <signal.h>. The signal () can pass only the signal number to the Signal Handler function whereas the function ‘sigaction ()’ has a third argument which is a structure holding the details of the received signal that can be passed on to the Signal Handler function.

This advantage of the ‘sigaction ()’ function comes at a cost of increasing code complexity and since the audience of this article are expected to be mostly beginners, a separate function has been written which uses the ‘sigaction ()’ function to set a particular function as Signal Handler. The function that can be set as a Signal Handler should have the same set of arguments and return value as shown in the following function prototype;

void signal_handler ( int sig, siginfo_t *siginfo, void *context );

In this project the function written to set the required function as Signal Handler using the ‘sigaction ()’ is named as ‘sig_set_handler ()’ and the details of the same are discussed below:

sig_set_handler ()

This function can be used to set a particular function as the Signal Handler for a particular signal number and hence the function has only two arguments, one for the signal number and the other for the function that need to be set as the Signal Handler. The prototype of the function is given below:

void sig_set_handler ( int signo, void *handler );

The first argument is the signal number that needs to be handled and the second argument is the pointer to the function that needs to be set as the Signal Handler. For example to set the following function as the Signal Handler using the ‘sig_set_handler ()’ for a signal ‘SIGUSR1’

void signal_handler ( int sig, siginfo_t *siginfo, void *context );

use the following statement in the code;

sig_set_handler ( SIGUSR1, &signal_handler );

A signal can be send to a process from another process using the using kill () function. But the kill () function is not able to send any values or message along with the signals. A function called ‘sigqueue ()’ is available in the <signal.h> which can be used to send values or messages along with the signals. Again using this function is also a bit complex and hence for the ease of programming a new function is written based on the ‘sigqueue ()’ to send value along with signals to another process. The function is called ‘sig_send_val ()’ and the details are discussed below;

sig_send_val ()

This function can be used to send a particular signal to a particular process along with a value and hence the function has three arguments, one for the process id, one for the signal number and the other for the value to be sent. The prototype of the function is given below;

void sig_send_val ( pid_t id, int signo, int val );

The first argument is the process id of the process to which the signal needs to be send and the second argument is the signal number of the signal to be send and the third argument is the value that needs to be send along with the signal. As an example to send the signal ‘SIGUSR1’ to a process with a process id 2107 along with a value 50, use the following statement;

sig_send_val ( 2107, SIGUSR1, 50 );

To retrieve the value send along with the signal inside the receiving function the structure pointer “siginfo -> si_value” can be used. For example the following statements of the Signal Handler function will print the value that passed on by the received signal.