Professional Documents
Culture Documents
CSEN2253 Processes & Threads Lab Assignments
CSEN2253 Processes & Threads Lab Assignments
c) ❯ pidof <proc_name>
For a running program named <proc_name> lists the process ids
There are other options which can be used along with ps command :
-a: Shows information about all users
-x: Shows information about processes without terminals
-u: Shows additional information like -f option
-e: Displays extended information
d) ❯ top
This command is used to show all the running processes within the working environment of
Linux.
e) ❯ kill pid
For processes running in background kill command can be used if it’s pid is known.
f) ❯ bg
A job control command that resumes suspended jobs while keeping them running in the
background
g) ❯ fg
It continues a stopped job by running it in the foreground.
Assignment II || Page 1 of 10
CSEN2253
OS Lab
2. Creating a process
Creating a process using fork()system call
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
fork();
// fork();
// fork();
printf("hello\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid;
int vble = 101;
printf("Before fork \n");
pid = fork();
Assignment II || Page 2 of 10
CSEN2253
OS Lab
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample() {
pid_t pid;
printf("Before fork \n");
printf("pid = %d, process_id = %d, parent_process_id = %d, \n\n", pid, getpid(),
getppid());
else if (pid > 0) {// parent process because return value non-zero and not -1.
printf("Hello from Parent!\n");
printf("fork = %d, process_id = %d, parent_process_id = %d, \n", pid,
getpid(), getppid());
}
int main()
{
forkexample();
return 0;
}
c) Understanding Parallel Execution of parent and child
fork() On success, the PID of the child process is returned in the parent, and 0 is returned in the child.
On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
Assignment II || Page 3 of 10
CSEN2253
OS Lab
3. Orphan Process
Parent does not invoke wait() but executes along with child process. In such a scenario when parent
process terminates before the child process, the child process becomes orphan. Orphan process is a
process that doesn’t have a parent process. This can happen when the parent process terminates due
to some reasons before the completion of the child.
An orphan process gets a new parent. The kernel detects that a process has become orphan and tries
to provide a new parent to the orphan process. In most cases, the new parent is the INIT process, one
with the PID 1. The new parent waits for the completion of the child (orphan process) and then asks the
kernel to clean the PCB of the orphan process.
fork
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid;
if ((pid = fork()) > 0) { // parent process
printf("I am Parent, my ID %d, I have child with ID: %d, My ParentID = %d\n\n",
getpid(), pid, getppid());
exit(10);
}
Assignment II || Page 4 of 10
CSEN2253
OS Lab
4. Zombie Process
Parent does not invoke wait() but executes along with child process. In such a scenario when child
process terminates before the parent process, it creates a zombie. Zombie process is that process which
has terminated but whose process control block has not been cleaned up from main memory because
the parent process was not waiting for the child. If there are a large number of zombie processes, their
PCBs IN WORST CASE can occupy the whole RAM.
fork
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid;
printf("Parent Process Id: %d\n",getpid());
pid=fork();
//parent process
while(1) { //infinite excution
sleep(1);
printf("\nParent Not invoked Wait()!");
}
/* parent will keep waiting without knowledge of child being made to exit.
as a result it still has an entry in the process table even though it has finished
execution.
This creates a resource leak.*/
return 0;
}
Assignment II || Page 5 of 10
CSEN2253
OS Lab
5. Shared memory space using vfork()
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t returnval;
int localvble = 20;
int childretval; // from child process: user provided return value
int exitstatus, i=0; // parent process : child's exit status
Assignment II || Page 6 of 10
CSEN2253
OS Lab
else if (returnval > 0) { // inside parent
sleep(2);
printf("PARENT:: My PID = %d, my Child's PID = %d, my parent's PID = %d
\n",getpid(), returnval, getppid());
printf("PARENT:: i = %d, local vble = %d, global vble =
%d\n\n",i,localvble,globalvble);
while (i < 10) {
printf("PARENT:: local vble = %d, global vble =
%d\n\n",localvble,globalvble);
++localvble; ++globalvble;
++i;
}
wait(&exitstatus);
printf("PARENT:: Child's exit code is -> %d \n",WEXITSTATUS(exitstatus));
printf("PARENT:: Good Bye\n\n");
exit(0); // parent process is terminating -- normally
}
} // outer-if complete....
else {
printf ("Child creation error....");
exit(0);
}
}
Predict the output from the print statements.
Assignment II || Page 7 of 10
CSEN2253
6. wait() ing by the parent
OS Lab
Can avoid unwanted situations like orphan and/or zombie
Wait
Parent (pid > 0) Parent resume
fork
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t returnval;
int localvble = 20;
int childretval; // from child process: user provided return value
int exitstatus, i=0; // parent process : child's exit status
Assignment II || Page 8 of 10
CSEN2253
OS Lab
else if (returnval > 0) { // inside parent
sleep(2);
printf("PARENT:: My PID = %d, my Child's PID = %d, my parent's PID = %d
\n",getpid(), returnval, getppid());
printf("PARENT:: i = %d, local vble = %d, global vble =
%d\n\n",i,localvble,globalvble);
while (i < 10) {
printf("PARENT:: local vble = %d, global vble =
%d\n\n",localvble,globalvble);
++localvble; ++globalvble;
++i;
}
sleep(2);
wait(&exitstatus);
printf("PARENT:: Child's exit code is -> %d \n",WEXITSTATUS(exitstatus));
printf("PARENT:: Good Bye\n\n");
exit(0); // parent process is terminating -- normally
}
} // outer-if complete....
else {
printf ("Child creation error....");
exit(0);
}
}
Compare the results of the last two programs and state the reason for their difference in behaviour.
7. Classwork
a) Write a program that accepts an integer num as command line argument. In your program create
two processes. One process should report the num! (Factorial of num). The other process should report
the summation of all factorials till num. [eg: if the argument is 5, one process calculates 5!=120, another
process calculates 1!+2!+3!+4!+5!=153]. Each process should report its pid, ppid, and child id.
b) Write a program to create exactly 3 processes. Each process should then display its own pid along
with the pid of the other two processes and tis relation with the other two processes
[grandparent/parent/child, parent/child-parent/child, parent/child/grandchild]. Take care so that
you don’t have any unwanted orphan/zombie process(es). Each process should report its pid, ppid,
and child id.
Assignment II || Page 9 of 10
CSEN2253
OS Lab
8. Home Assignment
a) Write a program that accepts two integers (low, high) as command line argument. Create two
processes in your program. The first process should calculate the summation of all integers between
(low, high) as sum_res. The second process should evaluate whether sum_res is prime or not.
Each process should report its pid, ppid, and child id.
b) Write a program to create exactly 3 processes. The program should accept two integers (min and
max) as command line arguments. The first process should report the even and odd numbers within
the range of min-max. The second process should report the prime and non-prime numbers within the
range min-max. The third process should report the summation of even numbers and prime numbers
within the range min-max.
Assignment II || Page 10 of 10
CSEN2253
WEEK – III Threads (I) OS Lab
1. Recall Basics about Threads
What is a Thread?
A thread is a path of execution within a process. A process can contain multiple threads.
Process vs Thread
The primary difference is that threads within the same process run in a shared memory space, while
processes run in separate memory spaces.
Threads are not independent of one another like processes are, and as a result, threads share with other
threads their code section, data section, and OS resources (like open files and signals).
Types of Threads
There are two types of threads.
User Level Thread
Kernel Level Thread
A thread does not maintain a list of created threads, nor does it know the thread that created it.
All threads within a process share the same address space.
/*creating thread*/
ret=pthread_create(&id,NULL,&threadFunction,NULL);
if(ret==0){
printf("Thread created successfully.\n");
}
else{
printf("Thread not created.\n");
return 0; /*return from main*/
}
while(1)
{
sleep(1);
printf("I am main function.\n");
}
return 0;
}
DESCRIPTION
The pthread_create() function starts a new thread in the calling process. The new thread starts
execution by invoking start_routine(); arg is passed as the sole argument of start_routine().
ARGUMENTS
thread - returns the thread id. (unsigned long int defined in bits/pthreadtypes.h)
attr - Set to NULL if default thread attributes are used. (else define members of the struct
pthread_attr_t defined in bits/pthreadtypes.h)
Attributes include:
• detached state (joinable? Default: PTHREAD_CREATE_JOINABLE.
Other option: PTHREAD_CREATE_DETACHED)
• scheduling policy (real-time?
PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)
• scheduling parameter
• inheritsched attribute (Default: PTHREAD_EXPLICIT_SCHED Inherit from parent thread:
PTHREAD_INHERIT_SCHED)
• scope (Kernel threads: PTHREAD_SCOPE_SYSTEM User threads: PTHREAD_SCOPE_PROCESS
Pick one or the other not both.)
• guard size
• stack address (See unistd.h and bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)
• stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h)
void * (*start_routine) - pointer to the function to be threaded. Function has a single argument:
pointer to void.
*arg - pointer to argument of function. To pass multiple arguments, send a pointer to a structure.
3. Terminating a Threads
Terminating a process using pthread_exit()function
SYNOPSIS
void pthread_exit(void *retval);
Compile and link with -pthread.
DESCRIPTION
The pthread_exit() function terminates the calling thread and returns a value via retval that (if the
thread is joinable) is available to another thread in the same process that calls pthread_join(3).
int main()
{
int i;
pthread_t tid;
pthread_exit(NULL);
return 0;
}
int main()
{
int i;
pthread_t tid, sid;
DESCRIPTION
The pthread_self() function returns the ID of the calling thread. This is the same value that is returned
in *thread in the pthread_create(3) call that created this thread.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int main()
{
int i;
pthread_t tid, sid;
6. Classwork
a) Write a program that accepts an integer num as command line argument. In your program create
two threads. One thread should report the num! (Factorial of num). The other thread should report the
summation of all factorials till num. [eg: if the argument is 5, one thread calculates 5!=120, another
thread calculates 1!+2!+3!+4!+5!=153]. Each process should report its own id and caller’s id. When a
thread ends, it should display meaningful message.
b) Write a program that accepts two integers (low, high) as command line argument. Create two
threads in your program. The first thread should calculate the summation of all integers between (low,
high) as sum_res. The second thread should evaluate whether sum_res is prime or not. Each process
should report its own id and caller’s id. When a thread ends, it should display meaningful message.
7. Home Assignment
a) Write a multi-threaded program such that it creates 10 more threads. Each thread should print Hello
from nth thread along with the argument received from the main thread. Each thread should return
its own id and a unique value to main using pthread_exit(). Main thread should be able to print
this returned message identifying which thread ended within its own thread.
i) Synchronize it such that all 10 threads are created first and then all of them are terminated.
Eg: 0 MAIN
1 created
2 created
3 created
.
.
.
.
10 created
1 ended
2 ended
3 ended
.
.
.
.
10 ended
MAIN ended
iii) Synchronize it such that a pair is created at a time and terminated in the reverse order of how
they were created.
Eg: 0 MAIN
1 created
2 created
2 ended
1 ended
3 created
4 created
4 ended
3 ended
.
.
.
.
9 created
10 created
10 ended
9 ended
MAIN ended