UNIX UNIT-4
PROCESS BASICS:
A process is a program in execution. OR A process is an executing instance of a program.
Every time you invoke a system utility or an application program from a shell, one or more
"child" processes are created by the shell in response. All UNIX processes are identified by a unique process identifier or PID. An important process that is always present is the init process.
This is the first process to be created when a UNIX system starts up and usually has a PID of 1.
All other processes are said to be "descendants" of init.
So, except for the first process, every process has a parent. UNIX permits a process to have multiple children.
The process image as viewed by the kernel runs in its own USER ADDRESS SPACE a protected space which can’t be disturbed by other users. This address space has a number of segments, which are explained in process structure.
Fig 1: UNIX Kernel Model
Files and processes have a lot in common. Files have attributes and so do processes. Most process attributes are stored in the process table, a separate structure maintained in memory by the kernel.
PROCESS STRUCTURE:
Process is an entity that can be assigned to processer for execution.
Process contains two elements
Program code
Data
PROCESS STATES:
New State: Process is just created.
Ready State: Process is in main memory and available for execution.
Waiting: Waiting for an I/O.
Running: Process is currently running.
Exit: Execution is completed.
Zombie: A Zombie state is a state which entered from running state when unexpected running error occurred, and then that process becomes Orphan process (Parent process link will break).
Every process has identifiers and states. dispatcher new ready
I/O complete
Process is just created running
I/O need waiting
Zombie exit
Fig 4.2: Process States
Dispatched is a program used to assign the Process to Processor.
Processer executes the process on interleaved passion.
Each process is allocated a unique number, a process identifier , or PID. The program code that will be executed by the grep command is stored in a disk file. The system libraries can also be shared. A process has its own stack space.
PROCESS STRUCTURE:
Every process will contains two kinds of DATA STRUCTURE, which are known as proc area structure and u area structure contains kernel related and user related information respectively .
Process table entry (Proc area)
• Contains general fields of processes that must be always be accessible to the kernel
–
User area (U area)
• further characteristics of the process only need to be accessible to the running process itself
Process table entry ( Proc area contains the table of structure)
• State field: user running, kernel running etc.
• Fields that allow the kernel to locate the process and u area. Requires while context switch
•
Process size : kernel know how much space to allocate for the process.
•
User ID
• Process ID
• Event descriptor.
• Used when the process is in the "sleep" state.
•
Scheduling parameters.
•
Allow the kernel to determine the order in which processes move to the states "kernel running" and "user running”
• A signal field.
• keeps the signals sent to a process but not yet handled.
• Various timers: process execution time, resource utilization etc.
•
A pointer to the process table entry
• User IDs
• various Timer:
– Execution time in user mode
– Execution Time in kernel mode
•
An error field: keeps error during system call
•
Return value field: result of system call
• I/O parameters
– Amount of data transfer
– Address of source and target etc.
•
The current directory and current root
•
User file descriptor table
• Limit fields
– Restrict process size
– Restrict size of the file it can write
•
The control terminal field:
– login terminal associated with the process, if one exists
•
An array indicates how the process wishes to react to signal
Starting a new process: fork() and vfork() fork() function:
Used to create a new process.
Unix kernel creates the new process, when an existing process calls the fork() function.
The new process created is called a child process
Syntax:
#include<sys/types.h>
#include<unistd.h>
Pid_t fork(void);
Returns : ‘0’in child
Process ID of child to parent ‘-1’ on error
Fork() function isn called once but returns twice because return value in the child is zero, return value in the parent is processn id nof a new child.
A process can have many childs but a child can have only one parent.
The child is a copy of parent
Eg : main()
{
fork();
Pf(“examples for fork()”);
}
O/P : example for fork
example for fork
fork() creates a child that is duplicate of the parent process.
The statements after the fork() will be executed once by parent and once by child.
The child process begins from fork().
The statement process before fork can only be executed by the parent process.
Eg : main()
{
printf(“before fork()”);
fork();
printf(“after fork()”);
}
O/P : before fork
After fork
After fork vfork() Funtion:
It is same as fork
Same calling sequence
Same return values as fork
Syntax
Pid_t vfork();
Returns:0 for child, process ID for parent.
Vfork () is to create a new process when the purpose of the purpose of the new process is to execute a new program.
The child process calls exec functions.
Address space of the parent not fully copied into the child i., child would not reference that address space.
The child just calls the exec function after the vfork.
Vfork guarantees that the child runs first until the child calls exec or exit.
When the child calls either of these functions the parent resumes. x1.c
main()
{
Pf(“%d”,getpid());
P”%d”,getppid()):
Vfork()
exec/(/usr/staff/ex2,”ex2”(char*/e));
} ex2.c: main()
{
Pf(“%d”,getpid());
Pf(“%d”,getppid());
}
Difference between fork() and Vfork():
During the fork(),the kernel makes a copy of the parent process’s address space and attaches it to the child process.
But the vfork() do not makes any copy of the parent’s address space. So it is faster than fork() .
The child process as a result of the vfork() executes the exec()
The child process from vfork() executes in the parent’s address space. This suspends the parent process until the child process exits.
WAITING FOR A PROCESS: wait(), waitpid() wait() function:
Used to wait/suspend the execution of a parent process until the child process execution is completed.
We can control the execution of the child process by calling the wait function in the parent process.
Wait() forces the parent to suspend the execution until the child execution is finished
Wait() blocks the parent until the child process termination.
Syntax
#include<syd/types.h>
#include<sys/wait.h>
Pid_t wait(int*stat log());
Returns : process ID if OK,-1 on error
Stat loc argument is a pointer to an integer where the unix system stores the status value returned by the child process.
Process table contains the status of each process, when child terminates. It s exit status placed
In the process table.
Then parent pickes up this status using the wait() function.
Eg: main()
{ int i; if(fork()==0)
{
for(i-0;i<=10;i++)
Pf(“%d”,i);
} else
{
Wait(0);
Pf(“parent process\n”);
}
.
.
} o/p:
1
2
.
9
10 waitpid function:
Used to suspend the execution of parent process until particular child process is terminated .
Syntax:
Pid_t pid (pid_t pid,int*stat loc, int options);
Returens:process ID if OK,-1 on error.
The options setting enables waitpid to run non blocking mode
Pid can take 4 types of values.
Pid = 1
Wait for any child
It is equivalent to wait() function
Pid>0
Waits for the child whose process ID is equals to pid.
Pid = 0
Waits for any child whose process group ID equals to the calling process.
Pid<-1
Waits for any child whose process group ID equals to the absolute value of pid.
Waits 3 and Wait 4 Function:
These are same as waitpid functions.
Returns summary of recourses used by the terminated process and its child process.
The recourses information includes the information about the amount of the user CPU time, the amount of the system CPU time and no. of signals received.
#include<sys/pipes.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/time.h>
#include<sys/resource.h>
Syntax
Pid_t wait 3(int*statloc,int options,struct rusage*rusage);
Pid_t wait 4(pid_t pid,int *statloc,int options struct rusage *rusage);
Both returens process ID if OK,-1 on error.
Difference between wait and wait pid:
Wait Waitpid
1) Parents process waits 1) Parent process waits for particular child
for any of its child to terminate. process to terminate.
2) wait blocks the parent. 2) waitpid doesn’t block the parent.
3) It takes signal argument 3) It takes two arguments.
Zombies:
A process is said to be zombies, that are dead but the information about the process cannot be removed from the process table.
In this case child process terminates before the parent process terminates.
Eg: main()
{
if(fork()>0)
{
Pf(“parent process\n”);
Sleep(50);
}
}
Zombie
Running in
User Mode
6 3 exit
Running in
Kernel Mode
4
Context
Switch
1
New
Process
5
Sleeping
Wakeup
2
Ready to Run
Fig : Life cycle of a Process with its system calls
1.
New process has no state.
2.
Process is ready to run but does not have CPU
3.
Context switch occurs and the process runs.
4.
System call occurs and the process switches to kernel mode
5.
Process tries a slow operation, so it is put to sleep.
6.
Process calls a system call to exit and becomes a Zombie.
+
PROCESS IDENTIFIER:
Every process has unique identifier i.e, a process ID.
Process ID is a non-negative integer.
Dispatcher process Id is 1, i.e, a parent for newly created processors.
Every process has 6 identifiers.
The following functions return identifiers for each process.
Every process has a unique process ID, a nonnegative integer.
There are some special processes. o Process ID 0 is usually the scheduler process and is often known as the swapper.
It is part of the kernel and is known as a system process
• Process ID 1 is usually the init process and is invoked by the kernel at the end of the bootstrap procedure.
•
The program file for this process was /etc/init .
•
This process is responsible for bringing up a Unix system after the kernel has been bootstrapped.
•
init usually reads the system-dependent initialization files (the /etc/rc* files) and brings the system to a certain state (such as multi-user).
•
In addition to the process ID, there are other identifiers for every process.
The following functions return these identifiers.
#include <sys/types.h>
#include <unistd.h> pid_t getpid(void);
Returns: process ID of calling process pid_t getppid(void);
Returns: parent process ID of calling process uid_t getuid(void);
Returns: real user ID of calling process uid_t geteuid(void);
Returns: effective user ID of calling process gid_t getgid(void);
Returns: real group ID of calling process gid_t getegid(void);
Returns: effective group ID of calling process
> Facts about fork():
• The new process created by fork is called the child process.
•
This function is called once but returns twice.
•
The return value in the child is 0 while the return value in the parent is the process ID of the new child.
•
The reason the child’s process ID is returned to the parent is because a process can have more than one child, so there is no function that allows a process to obtain the process
IDs of its children.
•
The reason fork returns 0 to the child is because a process can have only a single parent, so the child can always call getppid to obtain the process ID of its parent.
• Process ID 0 is always in use by the swapper, so its not possible for 0 to be the process
ID of a child.
•
Both the child and parent continue executing with the instruction that follows the call to fork .
•
The child is a copy of the parent.
•
For example, the child gets a copy of the parent’s data space, heap, and stack.
• Note that this is a copy for the child – the parent and child do not share these portions of memory.
•
Often the parent and child share the text segment (code), if it is read-only.
Process Termination:
There are eight ways for a process to terminate.
Normal termination occurs in five ways:
1. Return from main
2. Calling exit
3. Calling _exit or _ Exit
4. Return of the last thread from its start routine
5. Calling pthread_exit from the last thread
Abnormal termination occurs in three ways:
6. Calling abort
7. Receipt of a signal
8.
Response of the last thread to a cancellation request.
If the main function returns, the exit function is called. If the start-up routine were coded in C (it is often coded in assembler) the call to main could look like exit(main(argc, argv)); exit() Functions:
Three functions terminate a program normally: _exit and _Exit , which return to the kernel immediately, and exit, which performs certain cleanup processing and then returns to the kernel.
#include <stdlib.h> void exit(int status); void Exit(int status);
#include <unistd.h> void exit(int status);
Historically, the exit function has always performed a clean shutdown of the standard I/O library: the fclose function is called for all open streams. the exit status was undefined if the end of the main function was reached without an explicit return statement or call to the exit function.
Returning an integer value from the main function is equivalent to calling exit with the same value. exit function :
These functions are used to terminate the process from execution.
In unix we have 2 ways to terminate the process from execution.
Normal termination.
Abnormal termination.
Normal Termination:
These are 3 ways for a process to terminate normally. a) Executing a return statement from the main function and it is equals to exit function.
Eg : main()
{
printf(“hi”);
return(0);
} b) By calling the exit function
This function can be used to terminate the process normally.
Syntax :
#include<stdlib.h>
Void exit (int status);
Eg : main()
{
Pf(“exit”);
Exit(0);
} c) By calling-exit() function
This function is also used to terminate the process normally.
Syntax
#include<stdlib.h>
Void_exit(int status);
Eg: main()
{
Pf(_(“_exit”);
_exit(0);
}
Abnormal Termination:
There are 2 ways in which a process can terminate abnormally. a) By calling
This function causes the program to terminate abnormally.
This function sends the SIGABART signal to the process.
Eg: main()
{
Pf(“hi”);
abort();
pf(“bye”);
} b) When process receives certain signals.
(ZOMBIE) Orphan Process:
Parent process terminates before the child process terminates, then that child process is called an orphan process.
Eg: main()
{ if(fork()==0)
{
Pf(“%d”,getpid());
Pf(“%d”,getppid());
} else
{
Sleep(20);
Pf(“%d”,getppid);
Pf(“parent process\n”);
}
}
Exec Funtions: (important)
Used to initiate the new programs.
Mainly used to execute the new programs .
These functions are called with in the process.
Currently executing process calls this functions to execute a new program.
When a process starts calls one of the exec functions. Then new program starts execution from its main function.
Exec replaces the current process with the brand new program.
The process ID doesn’t change across an exec because a new process is not created.
There are 6 different exec functions but at a time we can use any one of the functions .
#include <unistd.h>
1) int exect (const char*pathname,const char *arg 0……../*(cahr*)0 */):
/*takes arg as list format*/
2)int execv(const char*pathname,char*const argv[]);
/*takes arg as ponter to an arrary of arguments*/
3)int execle (const char* pathname,const char *arg 0/);
/*takes arg in the form of list */
4)int execve(const char *pathname,char*const argv[]’char *const envp[]);
5)int execlp(const char *filename,const char*arg 0………);
6)int execvp(const char * filename,char*const argv[]);
All six returns-1 on error, no return on success.
Eg: main ()
{
Char temp[3];
temp[0]=”ls”;
temp [1]=”-l”;
temp[2]=(char*)0;
execv(“bin/ls”,temp);
} o/p: ls –l;
pre no.of links
acess time
size ex1.c main()
{
Printf(%d”,getpid());
Printf(“%d”,getppid());
execl(“user/staff/ex2”,”ex2”,(char*)0);
} ex2.c
{
Pf(“%d”, getpid());
Pf(“%d”,getppid()); }
This function can be used to execute the commands with in a program.
Syntax:
Example:
#include<stdio.h> int system(const char *cmd string);
#include<stdlib.h> int main()
{
System(“/s”);
}
Output : List of files in a present working directory.
If(cmd=IPC_STAT) : Fetch the semid_ds structure.
If(cmd=IPC_RMID) : Remove the Semaphore set from the system
If(cmd=IPC_SET) : Set the sem_perm.uid , sem_perm.gid , sem_perm.mode.
If(cmd=GETVAL) : get the semaphore value
If(cmd=SETVAL) : to set the value to semaphore.