next next up down toc toc news schedule screensaver allInOne PDF PDF mail
all, section 6.4.

6.4.  Classical Problems

For a description of the problem take a look to the board.

An implemation of a philosopher may be:

void philosopher(int i)

[picture]

Is this an acceptable solution?

What do you think about:

void philosopher(int i)

[picture]

A C-program:

 1      #include <stdio.h>
 2      #include "semaphore.h"
 3      
 4      #define MAX_PHIL    10
 5      #define MAX      2
 6      
 7      semaphore mySem;
 8      
 9      void e_critical_region(int n_phil )
10      {
11         printf("### %d wants to entry in critical region\n",n_phil);
12      
13         P(&mySem,n_phil);
14      
15         printf("### %d is in critical region\n",n_phil);
16      }
17      
18      void l_critical_region(int n_phil )
19      {
20         V(&mySem,n_phil);
21      
22         printf("### %d leaves critical region\n",n_phil);
23      }
24      
25      void take_fork(int i, int n_phil )
26      {
27         printf("--> %d fork nr. %d\n",n_phil, i);
28      }
29      
30      void put_fork(int i, int n_phil )
31      {
32         printf("<-- %d fork nr. %d\n",n_phil, i);
33      }
34      
35      void eat( int n_phil )
36      {
37         sleep(3);
38         printf("+++ %d eats\n",n_phil);
39      }
40      
41      void think(int n_phil)
42      {
43         printf("??? %d thinks\n",n_phil);
44      }
45      
46      void phil(int i)
47      {
48         int count = 0;
49      
50         printf("Philosoph %d is born\n", i);
51      
52              while ( count++ < MAX )
53              {
54                 think(i);                        /* think */
55                  e_critical_region(i);           /* entry c. r. */
56                  take_fork(i, i);                /* left fork */
57                  take_fork((i+1) % MAX_PHIL, i );/* rechte fork */
58                  eat(i);                         /* Mahlzeit */
59                  put_fork(i, i);                 /* left fork */
60                  put_fork( (i+1) % MAX_PHIL ,i );/* left fork */
61                  l_critical_region(i);           /* entry c. r. */
62              }
63      }
64      
65      
66      int create_p(int index)
67      {
68         int pid;
69      
70         switch ( ( pid = vfork() )  )   {
71            case -1:   perror("fork failed");
72                  exit(1);
73            case  0:   phil(index);
74                  exit(0);
75            default:   return pid;
76         }
77      
78      }
79      
80      int main(void)
81      {
82         int index;
83      
84         init_sem(&mySem);
85         for ( index = 0; index < MAX_PHIL; index ++ )
86            create_p(index);
87      
88         for ( index = 0; index < MAX_PHIL; index ++ )
89            wait(NULL);
90      
91         return 0;
92      }

Source Code: Src/7/phil.c

A test run:

gcc -o phil phil.c  semaphore.c
semaphore.c: In function `P':
semaphore.c:18: warning: passing arg 1 of `fprintf' makes pointer from integer without a cast
paltair Src 155 phil
Philosoph 0 is born
??? 0 thinks
### 0 wants to entry in critical region
### 0 is in critical region
--> 0 fork nr. 0
--> 0 fork nr. 1
+++ 0 eats
<-- 0 fork nr. 0
<-- 0 fork nr. 1
### 0 leaves critical region
??? 0 thinks
### 0 wants to entry in critical region
### 0 is in critical region
--> 0 fork nr. 0
--> 0 fork nr. 1
+++ 0 eats
<-- 0 fork nr. 0
<-- 0 fork nr. 1
### 0 leaves critical region
Philosoph 1 is born
??? 1 thinks
### 1 wants to entry in critical region
### 1 is in critical region
--> 1 fork nr. 1
--> 1 fork nr. 2
^C

Producer-Consumer Problem

Two processes share a common fixed size buffer. One of them, the producer, puts information into the buffer and the consumer takes it out.

Trouble arises when the producer wants to put a new item in the buffer, but it is already full. Similarily, if the consumer wants to remove an item from the buffer when the buffer is empty.

We will use three semaphores to solve this problem.

What do you think about:

#define N       100
#define FOREVER 1
typedef int semaphore;

semaphore mutex = 1;    /* access the buffer semaphore */
semaphore empty = N;    /* number of emtpy slots */
semaphore full  = 0;    /* number of used slots */

void producer(void)
{
int item;
        while ( FOREVER )       {
            item = produce_item();  /* create one */
            P(&empty);           /* decrement count of full slots */
            P(&mutex);           /* enter critical region */
            insert_item(item);
            V(&mutex);           /* leave critical region */
            V(&full);            /* increment count of full slots */
}

void consumer(void)
{
int item;
        while ( FOREVER )       {
            P(&full);            /* decrement count of full slots */
            P(&mutex);           /* enter critical region */
            consume_item(item);  /* take it */
            V(&mutex);           /*  enter critical region */
            V(&empty);           /* increment count of full slots */
            work_with_(item);       
}

What do you think about:

#define N       100
#define FOREVER 1
typedef int semaphore;

semaphore mutex = 1;    /* access the buffer semaphore */
semaphore empty = N;    /* number of emtpy slots */
semaphore full  = 0;    /* number of used slots */

void producer(void)
{
int item;
        while ( FOREVER )       {
            item = produce_item();  /* create one */
            P(&mutex);              /* enter critical region */
            P(&empty);              /* decrement count of full slots */
            insert_item(item);
            V(&mutex);              /* leave critical region */
            V(&full);               /* increment count of full slots */
}

void consumer(void)
{
int item;
        while ( FOREVER )       {
            P(&full);            /* decrement count of full slots */
            P(&mutex);           /* enter critical region */
            consume_item(item);  /* take it */
            V(&mutex);           /*  enter critical region */
            V(&empty);           /* increment count of full slots */
            work_with_(item);       
}

SORRY, its only for me.

--
Die beiden P-Operationen des Erzeugers sind ausgeführt.
--
Falls der Puffer voll ist, wird der Erzeuger blockiert und mutex erhält den Wert 0.
--
Wenn der Verbraucher das nächste Mal auf den Puffer zugreifen möchte, ist ihm dies nicht möglich [larr] deadlock
--
Wir untersuchen deadlock etwas später.

Please see also here:

Musical Chairs


back next up down toc toc news schedule screensaver allInOne pdf PDF mail

Created by unroff, java2html & & hp-tools. © by csfac. All Rights Reserved (2001).
It is not allowed to print these pages on a CAST printer.
Last modified: 05/November/01 (16:29)