UNIX Process and Signals

Process: 
A process is an instance of running a program. Kernel is responsible for most of all processes. Process is viewed by kernel and runs in its own address space. It is divided into three segments: Instruction or Text segment – contains executable code, Data segment – contains variables and arrays, User segment – contains process attributes.
     Every time you issue a command, Unix starts a new process, and suspends the current process (the C-shell) until the new process completes (except in the case of background processes).
    UNIX identifies every process by a Process Identification Number (PID) which is assigned when the process is initiated. When we want to perform an operation on a process, we usually refer to it by its pid.
    UNIX is time sharing system, which means that the processes take turns running. Each turn is called a timeslice: on most systems this is set at much less than one second. The reason this turns-taking approach is used is fairness: We don’t want a 2-second job to have to wait for a 5-hour job to finish, which is what would happen if a job had the CPU to itself until it completed.
Process structure:   
The term process structure generally corresponds to the several stages of a process, that it undergoes till the point of starting to terminate. The kernel deals with process structured maintaining a process record. Each process record consists of following information.
 
Parent process:

             Process ID.
·         Parent Process ID.
·         Terminal name.
·         The real user ID.
·         The real group ID.
·         The information about the controlling terminal.
·         The starting calendar time of a process.
·         The amount of CPU time utilized by a user.
·         The elapsed time.
·         The amount of memory utilized.
·         The data read or written.
·         The blocks read or written.
·         The various commands names respectively.
Starting a new Process:
      In Unix a process is created using the fork function by any of the existing process is called the child process and the process which has created the new process is known as the parent process. The newly created process retains a value of ‘0’ whereas the parent process is the process ID of new child under the fork function.
#include<sys/type.h>
#include<unistd.h>
pid_t fork (void);
On creation of above function the child process is created where child process ID is given to parent and child remains with a value 0 or returns a value -1 to indicate error.
Waiting for a process:
            In unix, we use two system calls for waiting a process until the other process has been exited. Those are wait() and waitpid(). In the following sections the syntaxes will be defined for these two system calls.
Zombie Process or Defunct Process:
            It is a process that has completed execution but still has an entry in the process table. So, the parent process may read its child exit status.
When a process finishes execution, it will have an exit status to report to its parent process. Because of this last little bit of information, the process will remain in the operating system’s process table as a zombie process, indicating that it is not to be scheduled for further execution, but that it cannot be completely removed (and its process ID cannot be reused) until it has been determined that the exit status is no longer needed.
When a child exits, the parent process will receive a SIGCHLD signal to indicate that one of its children has finished executing; the parent process will typically call the wait() system call at this point. That call will provide the parent with the child’s exit status, and will cause the child to be reaped, or removed from the process table.
Process Control:
     The process control has its own three different types of independent mechanism. The following mentioned are the three of them:
1.    Process creation.
2.    Process execution.
3.    Process termination.
Process Creation:
     In Unix a process is created using the fork function by any of the existing process is called the child process and the process which has created the new process is known as the parent process. The newly created process retains a value of ‘0’ whereas the parent process is the process ID of new child under the fork function.
#include<sys/type.h>
#include<unistd.h>
pid_t fork (void);
On creation of above function the child process is created where child process ID is given to parent and child remains with a value 0 or returns a value -1 to indicate error.
Process Execution:
     Once the child and parent process are created they both started executing the statement(which are followed by the process of creation). During this execution the child process gains few features of the parents like data space, root directory, session ID, process group ID etc.,
Process Termination:
      There are two ways in which the process can be terminated namely ‘normal termination’ and ‘abnormal termination’
Normal Termination:
1. Executing a return from the main function. This is equivalent to calling exit.
2. Calling the exit function.
If the above are the cases for terminating the process then it is known as the normal termination.
Abnormal Termination:
1.    Calling abort.
2.    When a process receives certain signals. The signals can be generated by the process itself( i.e., calling abort function).
If the above are the cases for terminating a process then it is known as the abnormal termination.
Process Identifier:
       Each and every process in unix have a unique ID, on non negative integer. Since the process ID is the only well known identifier of a process that is always unique, it is often used as a piece of other identifiers, to guarantee uniqueness
System call Interface for Process Management:
fork(): It creates a new process, but it does not initialize it from a new program.
     Syntax: #include<unistd.h>
                   pid_t  fork(void);
    After fork returns, both processes( parent and child) receive the return. The child receives a 0 return value from fork; the parent receives the process-ID of the child.
vfork():It creates a new process but the child process uses the same data segment of the parent process.
     Syntax: #include<unistd.h>
                   pid_t vfork(void);
      It returns child process Id and 0 on success and -1 on error.
exit system calls:
            These are used to terminate the process. There are exactly four ways that a process can terminate.
1.    Calling exit
2.    Calling _exit or _Exit.
3.    Receiving a terminating signal.
4.    A system crash, caused by anything from a power failure to a bug in the OS.
_exit:Technically _exit is from UNIX. It terminates process without cleanup.
          Syntax: #include<unistd.h>
                        void  _exit(int status);
         It doesn’t return any value.
exit: Technically exit is from Standard C. It terminates process with cleanup.
        Syntax:#include<stdlib.h>
                        void  exit(int status);
         It doesn’t return any value.
_Exit: Technically _Exit is from Standard C. It terminates process without cleanup.
        Syntax:#include<stdlib.h>
                        void  _Exit(int status);
         It doesn’t return any value.
wait system call:
            It suspends the execution of the current process until the child process has completed.
            Syntax: #include<sys/wait.h>
                           pid_t wait(int *statusp);     // pointer to status or NULL
            It returns process id on success or -1 on error.
waitpid system call:
            Wait for the child process to change state. It suspends the execution of the concurrent process until the child process as specified by the pid argument has exited.
            Syntax: #include<sys/wait.h>
                           pid_t waitpid(pid_t pid,
                                               int *status,
    int options);
            It returns process id or 0 on success or -1 on error.
options argument value
Description
>0
Wait for the child process with that process ID
-1
Wait for any child process
0
Wait for any child process in the same process group as the calling process
                                    <-1
Wait for any child process in the same process group whose process group ID is pid
exec system calls:
            The exec system calls reinitialize a process from a designated program. Actually there is no system call named “exec”. The so-called “exec” system calls are a set of six, with names of the form execAB, Where A is either l or v, depending on whether the arguments are directly in the call(list) or in an array(vector), and B is either, a p to indicate that the PATH environment variable should be used to search for the program, or an e to indicate that a particular environment is to be used. Thus, the six names are
1) execl          2 ) execv        3) execlp        4) execvp       5) execle        6) execve
1) execl:  It execute file with argument list
            Syntax: #include<unistd.h>
                        int execl(
                              const char  *path,           /*program pathname*/
                                const char  *arg0,         /*first arg (file name)*/
                               const char *arg1,           /*secong arg (if needed)*/
                               …………………..           /*remaining args (if needed)*/
                               (char *)NULL                  /*arg list terminator*/
                        );
            It returns -1 for error and returns no value if success.
 2) execv: It execute file with argument vector
            Syntax: #include<unistd.h>
                          int execv(
                                    const char *path,      /*program pathname*/
                                    char * const argv[]    /*argument vector*/
                           );
            It returns -1 for error and returns no value if success.
3) execlp:  It execute file with argument list and PATH search
            Syntax: #include<unistd.h>
                        int execlp(
                              const char  *file, /*program filename*/
                                const char  *arg0,         /*first arg (file name)*/
                               const char *arg1,           /*secong arg (if needed)*/
                               …………………..           /*remaining args (if needed)*/
                               (char *)NULL                  /*arg list terminator*/
                        );
            It returns -1 for error and returns no value if success.
4) execvp: It execute file with argument vector and PATH search
            Syntax: #include<unistd.h>
                          int execvp(
                                    const char *file,        /*program pathname*/
                                    char * const argv[]    /*argument vector*/
                           );
            It returns -1 for error and returns no value if success.
5) execle:  It execute file with argument list and environment
            Syntax: #include<unistd.h>
                        int execle(
                              const char  *path,           /*program filename*/
                                const char  *arg0,         /*first arg (file name)*/
                               const char *arg1,           /*secong arg (if needed)*/
                               …………………..           /*remaining args (if needed)*/
                               (char *)NULL                  /*arg list terminator*/
                               char * const envv[]        /*environment vector*/
                        );
            It returns -1 for error and returns no value if success.
6) execve: It execute file with argument vector and environment
            Syntax: #include<unistd.h>
                          int execve(
                                    const char *path,      /*program pathname*/
                                    char * const argv[]    /*argument vector*/
                                    char * const envv[]   /*environment vector*/
  );
            It returns -1 for error and returns no value if success.
System:
            It is used to execute the shell commands in the commands in the specified string.
            Syntax: #include<stdlib.h>
                           int system(const char *string);
            It returns status of the command on success or -1 on error.
Signal:
            It is a notification that an event has occurred such as user typing interrupt (ctrl+c), floating point exception or an alarm going off.
Signal functions:
1)    signal :
syntax : #include<signal.h>
                               void (*signal(
                                          int singnum,
                                              void (*act)(int))(int);
Here signum indicates signal number and act indicates signal action.
It returns old action or SIG_ERR for error.
2)    sighold : It is used to block a signal.
Syntax : #include<signal.h>
                int sighold(int signum);
It returns 0 on success or –1 on error.
3)    Sigrelse : It is used to release a signal.
Syntax : #include<signal.h>
                int sigrelse(int signum);
It returns 0 on success or –1 on error.
4)    sigignore : It is used to ignore a signal when rises.
Syntax : #include<signal.h>
                int sigignore(int signum);
It returns 0 on success or –1 on error.
Unreliable signals : It means that signal could get loss. A signal can occur but process would never know about that signal.
Unreliable signals are those for which the signal handler does not remain installed once called. These “one-shot” signals must re-install the signal handler within the signal handler itself, if the program wishes the signal to remain installed. Because of this, there is a race condition in which the signal can arrive again before the handler is re-installed, which can cause the signal to either be lost or for the original behavior of the signal to be triggered (such as killing the process). Therefore, these signals are “unreliable” because the signal catching and handler re-installation operations are nonatomic.
Interrupted system call : It is a system call within the kernel that is interrupted when the signal is caught. It is of 2 types.
1)    Slow system calls : It is used to block the signals.
2)    Others : Normal calls.
The slow system calls are those that can block forever. Included in this category are
·         Reads that can block the caller forever if data isn’t present with certain file types (pipes, terminal devices, and network devices)
·         Writes that can block the caller forever if the data can’t be accepted immediately by these same file types
·         Opens that block until some condition occurs on certain file types (such as an open of a terminal device that waits until an attached modem answers the phone)
·         The pausefunction (which by definition puts the calling process to sleep until a signal is caught) and the waitfunction
·         Certain ioctloperations
·         Some of the interprocess communication functions
The notable exception to these slow system calls is anything related to disk I/O. Although a read or a write of a disk file can block the caller temporarily (while the disk driver queues the request and then the request is executed), unless a hardware error occurs, the I/O operation always returns and unblocks the caller quickly.
kill : It is used to generate a signal explicitly for a process.
Syntax : #include<signal.h>
                int kill(pid_t pid,
    int signum);
It returns 0 on success or –1 on error.
raise : It is used to generate a signal explicitly for a thread.
Syntax : #include<signal.h>
                int raise(int signum);
It returns 0 on success or non-zero value on error.
alarm :It generates a signal when the alarm goes off.
Syntax : #include<unistd.h>
                 unsigned alarm(unsigned sec);
It returns seconds left on previous alarm or 0 if none.
pause :It is used to wait for a signal.
Syntax : #include<unistd.h>
                int pause(void);
It returns -1 on error.
abort  : It is used to generate a signal SIGABRT.
Syntax : #include<stdlib.h>
                void abort(void);
It doesn’t return any value.
sleep :It blocks a thread until the specified number of seconds has completed.
Syntax : #include<unistd.h>
                unsigned sleep(unsigned seconds);

It returns unslept amount on error or 0 if time has elapsed.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Enable Notifications OK No thanks