2. Unbounded-buffer producer-consumer
Problem:
#define N 100 /*number of slots in the buffer*/
int count = 0;/*number of items in the buffer*/
void producer(void) The problem we have here is a race condition.
{
int item;
while(TRUE){ /*repeated indefinitely*/
item = produce_item(); /*generates the next item*/
if(count == N)sleep(); /*If the buffer is full, becomes inactive*/
insert_item(item);/*put the item in the buffer*/
count = count + 1; /*increases the count of items in the buffer*/
if(count == 1) wakeup(consumer);/*checks whether the buffer was empty*/
}
}
void consumer(void)
{
int item;
while(TRUE) { /*checks whether the buffer was empty*/
if(count == 0)sleep(); /*if buffer is empty, it goes to inactive state*/
item = remove_item();/*removes the element from the buffer*/
count = count - 1; /*Decreases the count of items in the buffer*/
if(count == N-1)wakeup(producer); /*checks whether the buffer was empty*/
consumer_item(item); /*print item*/
}
}
3. Unbounded-buffer producer-consumer
Solution:
#define N 100 /*number of slots in the buffer*/
typedef int semaphore; /*semaphores are a kind of int*/
semaforo mutual = 1;/*controls access to the critical region*/ Solving this problem by semaphores.
semaforo empty = N;/*count the empty slots*/
semaforo full = 0;/*count the full slots*/
void producer(void)
{
int item;
while(TRUE){ /*TRUE is constant 1*/
item = produce_item(); /* generates something to put in the buffer*/
down(&empty);
down(&mutual);
insert_element(element);
up(&mutual);
up(&full);
}
}
void consumer(void)
{
int item;
while(TRUE) {
down(&full);
down(&mutual);
item = remove_consumer();
up(&mutual);
up(&full);
consumer_item(item);
}
}
4. Unbounded-buffer producer-consumer with
locks
Lock *l;
Condition *c;
int avail = 0;
void consumer(int dummy) {
while (1) {
This one solution from some ways to
l->Acquire();
if (avail == 0) { solve consumer-producer problem.
c->Wait(l);
}
consume the next unit of data
avail--;
l->Release();
}
}
void producer(int dummy) {
while (1) {
l->Acquire();
produce the next unit of data
avail++;
c->Signal(l);
l->Release();
}
}
void main() {
l = new Lock("l");
c = new Condition("c");
Thread *t = new Thread("consumer");
t->Fork(consumer, 1);
Thread *t = new Thread("consumer");
t->Fork(consumer, 2);
t = new Thread("producer");
t->Fork(producer, 1);
}
5. Eliminate deadlock
void do() {
l2->Acquire();
if (l1->TryAcquire())
l1->Acquire();
{
l2->Acquire();
do something...
l3->Acquire();
} else {
l4->Acquire();
l2->Release();
l5->Acquire();
l1->Acquire();
l2->Acquire();
do something...
l1->Release();
}
l2->Release();
}
6. How to detect and eliminate deadlock in the
dining philosophers problem.
Problem:
Five philosophers are seated around a circular table, each
philosopher has a plate of spaghetti. The spaghetti is so
slippery that a philosopher needs twoforks to eat. Between
each pair of dishes are a fork, when a philosopher is hungry, try
to buy their left and right forks, one at a time, in any order. If
successful in acquiring two forks, eating for a moment, then let
the forks andcontinue to think.
7. How to detect and eliminate deadlock in the
dining philosophers problem.
Solution:
void TAKE_FORK(int i) /*i number of philosopher from 0 to N-1*/
#define N 5 /*number of philosophers*/ {
#define LEFT (i+N-1)%N /*number of left neighbor*/ down(&mutex);/*enters the critical region*/
#define RIGHT (i+1)%N /*number of right neighbor*/ state[i] = HUNGRY;/*records the philosopher who is eating*/
#define THINKING 0 /*Philosopher is thinking*/ TRY(i);/*attempts to acquire 2 forks*/
#define HUNGRY 1 /* Philosopher is hungry*/ up(&mutex)/*leaves the critical region*/;
#define EATING 2 /*Philosopher is eating*/ down(&s[i]);/*crashes if the holders were not acquired*/
typedef int semaphore; /*semaphores are a kind of int*/ }
int state[N]; /*array that keeps track of the status of all*/ void PUT_FORK(int i) /*i number of philosopher from 0 to N-1*/
semaphore mutex = 1;/*mutual exclusion for critical regions following*/ {
semaphore s[N];/*a semaphore by philosopher*/ down(&mutex);/*enters the critical region*/
state[i] = THINKING;/*records the philsopher who is
void philosopher(int i)/*i number of philosopher from 0 to N-1*/ eating*/
{ TRY(LEFT);/*attempts to acquire the left fork*/
while(TRUE){/*repeated indefinitely*/ TRY(RIGHT);/*attempts to acquire the right fork*/
THINKING();/*the philosophers is thinking*/ up(&mutex);leaves the critical region*/
TAKE_FORK(i);/*the philosopher takes the fork*/ }
EAT();/*the philosopher is eating*/ void TRY(i) /*i number of philosopher from 0 to N-1*/
PUT_FORK(i);/*philosopher put the fork*/ {
} if(state[i] == HUNGRY && state[LEFT] != EATING &&
} state[RIGHT] != EATING){
state[i] = EATING;
up(&s[i]);
}
}
8. Suspend and Resume algorithm
The worst case is when the lock is The SR algorithm costs twice the
unlocked just after the thread starts the suspend and resume time. It first spins
suspend. for the suspend and resume time, then
suspends, then gets the lock, then
resume.
The optimal algorithm just spins until
the lock is unlocked, taking the suspend
and resume time to acquire the lock.