You are on page 1of 5

LAB MANUAL Operating Systems

Lab 3_ Process Creation

1. Fork() System Call:


Fork system call is used for creating a new process, which is called child process, which runs
concurrently with the process that makes the fork() call (parent process). After a new child process
is created, both processes will execute the next instruction following the fork() system call. A child
process uses the same pc(program counter), same CPU registers, same open files which use in the
parent process.
It takes no parameters and returns an Integer value. Below are different values returned by fork().
Negative Value: creation of a child process was unsuccessful.
Zero: Returned to the newly created child process.
Positive value: Returned to parent or caller. The value contains process ID of newly created child
process.
Example Code:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample()
{
// child process because return value zero
if (fork() == 0)
printf("Hello from Child!\n");

// parent process because return value non-zero.


else
printf("Hello from Parent!\n");
}
int main()
{
forkexample();
return 0;
}

Output:
1.
Hello from Child!
Hello from Parent!
(or)
2.
Hello from Parent!
Hello from Child!
In the above code, a child process is created, fork() returns 0 in the child process and positive
integer to the parent process.
Here, two outputs are possible because the parent process and child process are running
concurrently. So, we do not know if OS first give control to which process a parent process or a
child process.
Important: Parent process and child process are running the same program, but it does not mean
they are identical. OS allocate different data and state for these two processes and control the
flow of these processes can be different.

2. getpid() System Call:

Pid is a process unique identity number. Every process can query its own process identifier using
the getpid().
#include <stdio.h>

* The return value of fork() is actually pid_t ('pid' 't'ype).


* When it is assigned to 'int pid', if the type is different, there
* is an implicit cast; however, when we print the return value
* of getpid(), it is necessary to explicitly cast it as an
* integer.
*
* The type 'pid_t' is defined in the library header <sys/types.h>
*/

int main( void ) {


printf( "The process identifier (pid) of the parent process is %d\n", (int)getpid() );

int pid = fork();

if ( pid == 0 ) {
printf( "After the fork, the process identifier (pid) "
"of the child is %d\n", (int)getpid() );
} else {
printf( "After the fork, the process identifier (pid) "
"of the parent is still %d\n - fork() returned %d\n",
(int)getpid(), pid );
}

return 0;
}
Output:
The process identifier (pid) of the parent process is 25201
After the fork, the process identifier (pid) of the child is 25202
After the fork, the process identifier (pid) of the parent is still 25201
- fork() returned 25202

Execute the code several times and observe, the change in pid values.

3. exec() family of System Calls:


There is a family of exec() functions, all of which have slightly different characteristics:

int execl ( const char *path, const char *arg, ... );


int execlp( const char *file, const char *arg, ... );
int execle( const char *path, const char *arg, ..., char *const envp[] );
int execv ( const char *path, char *const argv[] );
int execvp( const char *file, char *const argv[] );
int execve( const char *file, char *const argv[], char *const envp[] );

The exec family of functions replaces the current running process with a new process. It can be
used to run a C program by using another C program. It comes under the header
file unistd.h. There are many members in the exec family which are shown below with
examples.
• execvp : Using this command, the created child process does not have to run the same
program as the parent process does. The exec type system calls allow a process to run any
program files, which include a binary executable or a shell script . Syntax:
int execvp (const char *file, char *const argv[]);
file: points to the file name associated with the file being executed.
argv: is a null terminated array of character pointers.
Let us see a small example to show how to use execvp() function in C. We will have two .C
files , EXEC.c and execDemo.c and we will replace the execDemo.c with EXEC.c by
calling execvp() function in execDemo.c .

//EXEC.c

#include<stdio.h>
#include<unistd.h>
int main()
{
int i;

printf("I am EXEC.c called by execvp() ");


printf("\n");

return 0;
}
Now,create an executable file of EXEC.c using command
gcc EXEC.c -o EXEC

//execDemo.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
//A null terminated array of character
//pointers
char *args[]={"./EXEC",NULL};
execvp(args[0],args);

/*All statements are ignored after execvp() call as this whole


process(execDemo.c) is replaced by another process (EXEC.c)
*/
printf("Ending-----");

return 0;
}
Now, create an executable file of execDemo.c using command
Example Code using execlp():
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
void main(int argc,char *arg[])
{
int pid; pid=fork();
if(pid<0)
{
printf("fork failed");
exit(0);
}
else if(pid==0)
{
execlp("whoami","ls",NULL);
exit(0);
}
else
{
wait(2);
printf("\n Parent Process id is %d\n",getpid());
exit(0);
}
}
Output:

saima
Parent Process id is 35233

Lab Assignment: (marks 20)


What is the output of the following codes?

1. Code 1: (5)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
fork();
printf("Hello world!\n");
return 0;
}

2. Code 2: (5)

#include <stdio.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hello\n");
return 0;
}

3. Write a code for the following output. Using exec() system call (10)

Child has x = 2
Parent has x = 0

You might also like