Lab 7
Lab 7
Lab 7
Pre-Lab Task
1.
A. Analyze the purpose of thread and write description for the following
pthread library Functions
1. pthread_create()
Syntax:
int pthread_create(pthread_t * thread,
const pthread_attr_t * attr,
void * (*start_routine)(void *),
void *arg);
Parameters:
thread: pointer to an unsigned integer value that returns the thread id of the thread
created.
attr: pointer to a structure that is used to define thread attributes like detached state,
scheduling policy, stack address, etc. Set to NULL for default thread attributes.
start_routine: pointer to a subroutine that is executed by the thread. The return type
and parameter type of the subroutine must be of type void *. The function has a single
attribute but if multiple values need to be passed to the function, a struct must be
used.
arg: pointer to void that contains the arguments to the function defined in the earlier
argument
2. pthread_exit()
Syntax:
void pthread_exit(void *retval);
Parameters: This method accepts a mandatory parameter retval which is the pointer
to an integer that stores the return status of the thread terminated. The scope of this
variable must be global so that any thread waiting to join this thread may read the
return status.
3. pthread_join()
Syntax:
int pthread_join(pthread_t th,
void **thread_return);
Parameter: This method accepts following parameters:
th: thread id of the thread for which the current thread waits.
thread_return: pointer to the location where the exit status of the thread mentioned
in th is stored.
4. pthread_self()
Syntax:
pthread_t pthread_self(void);
5. pthread_cancel()
Syntax:
int pthread_cancel(pthread_t thread);
Parameter: This method accepts a mandatory parameter thread which is the thread id
of the thread to which cancel request is sent.
6. pthread_detach()
Syntax:
int pthread_detach(pthread_t thread);
Parameter: This method accepts a mandatory parameter thread which is the thread id
of the thread that must be detached.
7. pthread_equal()
Syntax:
int pthread_equal(pthread_t t1,
pthread_t t2);
Parameters: This method accepts following parameters:
t1: the thread id of the first thread
t2: the thread id of the second thread
8. pthread_mutex_init()
9. pthread_mutex_destroy()
10.pthread_mutex_lock()
11.pthread_mutex_trylock()
12.pthread_mutex_unlock()
B. Write description for the following calls and match them with their functions
Sl no
call functions
1 sem_post() (e) (a)wait on a named or unnamed semaphore
2 sem_wait() (a) (b)remove a named semaphore(REAL TIME)
3 sem_open() (d) (c) get the value of a semaphore
4 sem_getvalue() (c) (d)initialise and open a named semaphore.
5 sem_unlink() (b) (e)unlock a semaphore (REALTIME).
2. Write a program to create 5 pthreads and display Hello world. Main thread
should wait until new threads are terminated
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int d=1;
void *myThreadFun(void *vargp)
{
int *myid = (int *)vargp;
printf("Thread %d ID: %d\t Printing : Hello World\n", d++,*myid);
}
int main()
{
int i;
pthread_t tid;
for (i = 0; i < 5; i++)
pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
pthread_exit(NULL);
return 0;
}
Output:
Thread 1 ID: 2 Printing : Hello World
Thread 2 ID: 3 Printing : Hello World
Thread 3 ID: 2 Printing : Hello World
Thread 4 ID: 4 Printing : Hello World
Thread 5 ID: 4 Printing : Hello World
#include<stdio.h>
#include<pthread.h>
int main()
{
printf("main start \n");
printf("Operating System\n");
printf("calling exit \n ");
pthread_exit(" ");
printf("Linux");
return 0;
}
Output:
main start
Operating System
calling exit
Output:
3
In-Lab
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int g = 0,d=0;
void *myThreadFun(void *vargp)
{
int *myid = (int *)vargp;
d++; ++g;
printf("Thread %d ID: %d, Global: %d\n", d,*myid, ++g);
}
int main()
{
int i;
pthread_t tid;
for (i = 0; i < 3; i++)
pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
pthread_exit(NULL);
return 0;
}
Output:
Thread 1 ID: 3, Global:2
Thread 2 ID: 3, Global:4
Thread 3 ID: 3, Global:6
#include<stdio.h>
#include<pthread.h>
void *sumNum(void *parg)
{
int n=(int *)parg;
int i, sum=0;
for(i=1;i<=n;i++)
sum=sum+i;
printf("Parallel Sum = %d\n",sum);
pthread_exit(NULL);
}
int main()
{
pthread_t p1,p2;
pthread_create(&p1,NULL,sumNum,10);
pthread_create(&p2,NULL,sumNum,5);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
return 0;
}
Output:
Parallel Sum = 55
Parallel Sum = 15
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t mutex,writeblock;
int data = 0,rcount = 0;
int main()
{
int i,b;
pthread_t rtid[5],wtid[5];
sem_init(&mutex,0,1);
sem_init(&writeblock,0,1);
for(i=0;i<=2;i++)
{
pthread_create(&wtid[i],NULL,writer,(void *)i);
pthread_join(wtid[i],NULL);
pthread_create(&rtid[i],NULL,reader,(void *)i);
pthread_join(rtid[i],NULL);
}
return 0;
}
Output:
Data written by the writer 0 is 1
Data read by the reader 0 is 1
#include<stdio.h>
int main()
{
int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 },{ 2, 0, 0 },{ 3, 0, 2 }, { 2, 1, 1 }, { 0, 0, 2 } };
int max[5][3] = { { 7, 5, 3 }, { 3, 2, 2 }, { 9, 0, 2 }, { 2, 2, 2 }, { 4, 3, 3 } };
int avail[3] = { 3, 3, 2 };
int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
return (0);
Output:
#include<stdio.h>
#include<stdlib.h>
int buffer,empty,full=0,mutex=1,op,x=0;
int wait(int s)
{
while(s<=0);
return --s;
}
int signal(int s)
{
return ++s;
}
void produce(){
if(mutex==1 && empty!=0)
{
mutex=wait(mutex);
full=signal(full);
empty=wait(empty);
mutex=signal(mutex);
++x;
printf("\n Producer produces an item %d \n\n",x);
}
else
printf("\n Buffer is Full , cannot produce\n");
void consume()
{
if(mutex==1 && full!=0)
{
mutex=wait(mutex);
full=wait(full);
empty=signal(empty);
mutex=signal(mutex);
printf("\n Consumer consumed an item %d \n\n",x);
--x;
}
else
printf("\n Buffer is Empty , cannot consume\n");
}
void main()
{
printf("Enter the buffer size ");
scanf("%d",&buffer);
empty=buffer;
while(1)
{
printf("\n \t choose the operation : ");
printf("\n1.produce\n2.consume\n3.exit\t>>>:");
scanf("%d",&op);
switch(op)
{
case 1: produce();
break;
case 2: consume();
break;
case 3: exit(0);
}
}
}
Output :
Enter the buffer size 2
choose the operation :
1.produce
2.consume
3.exit >>>:1
Producer produces an item 1
choose the operation :
1.produce
2.consume
3.exit >>>:1
Producer produces an item 2
choose the operation :
1.produce
2.consume
3.exit >>>:1
Buffer is Full , cannot produce
choose the operation :
1.produce
2.consume
3.exit >>>:2
Consumer consumed an item 2
choose the operation :
1.produce
2.consume
3.exit >>>:2
Consumer consumed an item 1
choose the operation :
1.produce
2.consume
3.exit >>>:2
Buffer is Empty , cannot consume
choose the operation :
1.produce
2.consume
3.exit >>>:3
2. Implement dining philosopher problem using semaphores and threads.
Suppose there are N philosophers meeting around a table, eating spaghetti
and talking about philosophy. Now let us discuss the problem. There are
only N forks available such that only one fork between each philosopher.
Since there are only 5 philosophers and each one requires 2 forks to eat, we
need to formulate an algorithm which ensures that the utmost number of
philosophers can eat spaghetti at once
To implement Dining Philosophers Problem using Threads and Semaphores
ALGORITHM- SEMAPHORES
ALGORITHM- THREAD
1. Start.
2. Philosopher i is thinking.
3. Lock the left fork spoon.
4. Lock the right fork spoon.
5. Philosopher i is eating.
6. sleep
7. Release the left fork spoon.
8. Release the right fork spoon.
9. Philosopher i Finished eating.
10.Stop.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
void *func(int n);
pthread_t philosopher[5];
pthread_mutex_t chopstick[5];
int main()
{
int i,k;
void *msg;
for(i=1;i<=5;i++)
{
k=pthread_mutex_init(&chopstick[i],NULL);
if(k==-1)
{
printf("\n Mutex initialization failed");
exit(1);
}
}
for(i=1;i<=5;i++)
{
k=pthread_create(&philosopher[i],NULL,(void *)func,(int *)i);
if(k!=0)
{
printf("\n Thread creation error \n");
exit(1);
}
}
for(i=1;i<=5;i++)
{
k=pthread_join(philosopher[i],&msg);
if(k!=0)
{
printf("\n Thread join failed \n");
exit(1);
}
}
for(i=1;i<=5;i++)
{
k=pthread_mutex_destroy(&chopstick[i]);
if(k!=0)
{
printf("\n Mutex Destroyed \n");
exit(1);
}
}
return 0;
}void *func(int n)
{
printf("\nPhilosopher %d is thinking ",n);
pthread_mutex_lock(&chopstick[n]);//when philosopher 5 is eating he takes fork 1
and fork 5
pthread_mutex_lock(&chopstick[(n+1)%5]);
printf("\nPhilosopher %d is eating ",n);
sleep(3);
pthread_mutex_unlock(&chopstick[n]);
pthread_mutex_unlock(&chopstick[(n+1)%5]);
printf("\nPhilosopher %d Finished eating ",n);
}
Output:
Philosopher 1 is thinking
Philosopher 1 is eating
Philosopher 2 is thinking
Philosopher 3 is thinking
Philosopher 3 is eating
Philosopher 4 is thinking
Philosopher 5 is thinking
Philosopher 1 Finished eating
Philosopher 3 Finished eating
Philosopher 4 is eating
Philosopher 5 is eating
Philosopher 2 is eating
Philosopher 4 Finished eating
Philosopher 5 Finished eating
Philosopher 2 Finished eating
Reference
>>>>>>>>>>>>>Banker’s Algorithm in Operating System
The banker’s algorithm is a resource allocation and deadlock avoidance algorithm
that tests for safety by simulating the allocation for predetermined maximum
possible amounts of all resources, then makes an “s-state” check to test for possible
activities, before deciding whether allocation should be allowed to continue.
Following Data structures are used to implement the Banker’s Algorithm:
Let ‘n’ be the number of processes in the system and ‘m’ be the number of
resources types.
Available :
It is a 1-d array of size ‘m’ indicating the number of available resources of
each type.
Available[ j ] = k means there are ‘k’ instances of resource type Rj
Max :
It is a 2-d array of size ‘n*m’ that defines the maximum demand of each
process in a system.
Max[ i, j ] = k means process Pi may request at most ‘k’ instances of resource
type Rj.
Allocation :
It is a 2-d array of size ‘n*m’ that defines the number of resources of each
type currently allocated to each process.
Allocation[ i, j ] = k means process Pi is currently allocated ‘k’ instances of
resource type Rj
Need :
It is a 2-d array of size ‘n*m’ that indicates the remaining resource need of
each process.
Need [ i, j ] = k means process Pi currently need ‘k’ instances of resource
type Rj
for its execution.
Need [ i, j ] = Max [ i, j ] – Allocation [ i, j ]
>>>>>>>>>>>>>Producer-Consumer Problem
But there may be situations where the producer produce and tries to put an item
into a full buffer. Similarly consumer may try to consume from an empty
buffer.Thus to achieve synchronization, the producer must be blocked when the
buffer is full and the consumer must be blocked when the buffer is empty. It is also
called as bounded buffer problem.
Write a
program to implement producer consumer problem.
ALGORITHM
Step 1: Start
Step 8:Stop
There are some Philosophers whose work is just thinking and eating. Let there are
5 (for example) philosophers. They sat at a round table for dinner. To complete
dinner each must need two Forks (spoons). But there are only 5 Forks available
(Forks always equal to no. of Philosophers) on table. They take in such a manner
that, first take left Fork and next right Fork. But problem is they try to take at same
time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1,
2, 3, 4, 5 respectively (since they are left side of each). And each one tries to ta ke
right side Fork. But no one found available Fork. And also that each one thinks that
someone will release the Fork and then I can eat. This continuous waiting leads to
Dead Lock situation.
Dining Arrangement
Solution: To solve this Dead Lock situation, Last philosopher (any one can do
this) first try to take right side fork and then left side fork. i.e in our example 5th
person tries to take 4th Fork instead of 5th one. Since 4th Fork already taken by 4th
the person, he gets nothing. But he left 5th Fork. Now the first person will take this
5th Fork and complete dinner and make 1st and 5th available for remaining people.
Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This
continuous until all finishes dinner.