Signals

In the early days of computing, signals were a means to deal with unusual events, and usually, their job was to reset a condition to a default state. Nowadays, with facilities such as job control, signals are used to actually instruct processes on what to do and are now more an interprocess facilities than a reset mechanism, as they were originally conceived. Each signal is associated to an action that must be performed by the process receiving it, so here is a brief list with some of the more interesting signals that the kernel can send to a process:

  • SIGCHLD: This signal is sent to a parent process when a child terminates or stops.
  • SIGCONT: This tells the process that has been put on hold by SIGSTOP or SGSTP to resume its execution. These three signals are used in job controlling.
  • SIGHUP: This signal is sent to a process when its terminal is closed and kills it. It owes its name to the old good times when connections were held over serial line, which hang up due to a line drop. If sent to a daemon, it usually forces them to reload the configuration file and reopen the log file.
  • SIGINT: This is the signal given to the process when a user presses Ctrl + C, and it interrupts the process, terminating it. This signal can be ignored by the process.
  • SIGKILL: This terminates a process immediately. This cannot be ignored, and the process has to die immediately without closing or saving anything. (kill -9)
  • SIGQUIT: When the process receives this signal, it quits performing a core dump. A core dump is a dump, a copy, of the memory used by the process, so we can find in it a lot of useful information such as a processor, registers, flags, data, which are useful to debug the working state of the process itself.
  • SIGSTOP: This signal is sent to stop a process. It cannot be ignored.
  • SIGTERM: It is a termination request. This is the preferable way to kill a process since it allows the process to shut down nicely, releasing the resources and saving state and also killing all the child processes in an orderly way. It can be ignored by the process (kill -15).
  • SIGTRAP: This is a signal sent to a process when an exception or a trap arises. We already had a glimpse of traps, and we will see more about them now.
  • SIGTSTP: This is an interactive stop, and it can be sent by the user pressing Ctrl+Z. It can be ignored by the process. The process pauses in its current state.
  • SIGTTIN: This signal is sent to a background process when it tries to read from the terminal.
  • SIGTTOU: This signal is sent to a background process when it tries to write to the terminal.
  • SIGSEV: This is sent to a process when it goes on segmentation fault, and this happens when a process attempts to access a memory location; it is not allowed to access or in a way it is not permitted.

So, we have signals, and we have process groups and sessions and this leads us to Unix job control. What is it? In Unix, we can control what we call jobs, and we are already familiar with those since this is another term to refer to process groups. A job is not a process, it is a group of processes. But what does control mean? Simply, we can suspend, resume, or terminate a job and send signals to it.

When a shell session is started on a terminal, its process group is granted access to it, and it becomes the foreground process group for that terminal. This means that the processes belonging to the foreground group can read and write from the terminal, while the processes belonging to other process groups are barred from accessing the terminal and stopped if they try to. So, from the shell, you can interact with the terminal and perform different actions, for example, retrieve a list of processes and their job ID:

zarrelli:~$ ps -fj | awk '{print $2 " -> " $4 " -> " $10 }'
PID -> PGID -> CMD
1422 -> 1422 -> /bin/bash
7886 -> 7886 -> ps
7887 -> 7886 -> awk

As we can see, the ps and awk processes have the same process group ID, which is the process ID of the first command in the group, ps. Now, what about the job control? Let's see how to start a process in the background:

zarrelli:~$ sleep 10 &
[1] 8163

The sleep command just waits for the amount of seconds we specify as an argument, but the ampersand is the key; it will put the process in the background. What we get in return is a job number [1] and a process ID; ps will show us more details:

zarrelli:~$ ps -jf
UID PID PPID PGID SID C STIME TTY TIME CMD
zarrelli 1422 1281 1422 1422 0 08:46 pts/0 00:00:00
/bin/bash
zarrelli 8163 1422 8163 1422 0 10:25 pts/0 00:00:00 sleep
10
zarrelli 8166 1422 8166 1422 0 10:25 pts/0 00:00:00 ps -jf

Now, let's have a look at this:

zarrelli:~$ (sleep 100 &) ; sleep 20 &
[1] 8632
zarrelli:~$:~$ ps -jf
UID PID PPID PGID SID C STIME TTY TIME CMD
zarrelli 1422 1281 1422 1422 0 08:46 pts/0 00:00:00
/bin/bash
zarrelli 8631 1 8630 1422 0 10:39 pts/0 00:00:00 sleep
100
zarrelli 8632 1422 8632 1422 0 10:39 pts/0 00:00:00 sleep
20
zarrelli 8637 1422 8637 1422 0 10:40 pts/0 00:00:00 ps -jf

Here, we put one sleep process in the background but used the () to execute it in the subshell, and it actually was executed in the foreground; but now, the main shell did not report any job or process ID because the child shell could not report back any information to the parent shell. The only job information we received was for the second sleep instruction performed in the parent shell, and interestingly, both the sleep processes have the same group ID.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.120.133