Aufgabe mit Semaphoren

Neue Frage »

Auf diesen Beitrag antworten »
deppensido Aufgabe mit Semaphoren

Hallo,

bei der Aufgabe (siehe Anhang) ist mir nicht klar, ob es zu Problemen bzgl der Ent-/Belademenge führen kann. Ich habe einige Prozessablauffolgen durchprobiert, aber meiner Meinung nach, passt das alles. Kann ich daraus schließen, dass es wirklich nicht zu Problemen kommen kann (3. Teil der Aufgabe).

Im folgenden poste ich mal meine Lösungen zu Teil 1 und 2. Habe ich hier alles richtig gemacht?

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
1)

benötigte Semaphoren: 

mutex(1) //damit die Laderampe nur von jeweils einem Prozess gleichzeitig verwendet werden kann, zu beginn ist die Laderampe frei 

empty(24) //zaehlt die entnommenen Teile der Lagerhalle, zu beginn ist die Lagerhalle leer → Platz für 24 Teile

Nachfolgende Semaphoren sind je mit 0 initialisiert, da die Lagerhalle zu beginn leer ist
server(0) // zählt die vorhandenen Server

dektoprechner(0) // zählt die vorhandenen DesktopRechner

monitor(0) // zählt die vorhandenen Monitore



2)

Prozess H
while(true) :
	for i=1 to 6 do
		P(empty) //Die Ware muss komplett abgeladen werden können (6 Teile)
	P(mutex) // Laderampe muss frei sein (kritischen Bereich betreten)
	Server_entladen(1)
	DesktopRechner_entladen(3)
	Monitore_entladen(2)
	V(mutex) //Laderampe verlassen (kritischen Bereich verlassen)
	V(server) // 1 Server wurde entladen
	for i=1 to 3 do
		V(desktoprechner) // 3 DesktopRechner wurden entladen
	V(monitor)
	V(monitor) //2 Monitore wurden entladen
	
	
Prozess D
while(true) :
	P(desktoprechner)
	P(monitor) // Es muss mindestens 1 DesktopRechner und 1 Monitor im Lager sein
	P(mutex) // Laderampe muss frei sein (kritischen Bereich betreten)
	DesktopRechner_entladen(1)
	Monitore_entladen(1)
	V(mutex) //Laderampe verlassen (kritischen Bereich verlassen)
	V(empty)
	V(empty) //Anzahl der entnommenen Teile um 2 erhöhen





Prozess S
while(true) :
	P(server) // es muss mindestens ein Server im Lager sein
	P(mutex) // Laderampe muss frei sein (kritischen Bereich betreten)
	Server_entladen(1)
	V(mutex) // Laderampe verlassen (kritischen Bereich verlassen)
	V(empty) // Anzahl der entnommenen Teile um 1 erhöhen


vielen Dank im voraus.
 
Auf diesen Beitrag antworten »
deppensido

ich habe mich nun an den letzten Teil der Aufgabe gemacht, also das Beispiel mit posix_threads in C implementiert. Allerdings bekomme ich es nicht hin das Programm auszuführen.
Meine Idee war zuerst "gcc Blatt5.c -lpthread" auszuführen und dann "gcc -o Blatt5 Blatt5.c" das erste lief noch Fehlerlos, beim zweiten bekomme ich einen Haufen Warnungen und Fehler. Wenn ich dann "gdb Blatt5" eingebe, kommt die Meldung "Datei oder Verzeichnis nicht gefunden. Ich arbeite übrigens über OpenSuse und nutze einen Texteditor (Kate) zum schreiben der Programme. Das Ausführen mach ich dann über das Terminal. Die Datei habe ich einfach Blatt5.c genannt.

Im folgenden mal der Code:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#define BUFFER_SIZE 24
//benötigte semaphoren
sem_t empty;
sem_t server;
sem_t desktoprechner;
sem_t monitor;
pthread_mutex_t mutex;

pthread_attr_t attr;

pthread_t ptid,dtid,stid; //Threads für 3 Prozesse

void *producerH(void *param);
void *consumerD(void *param);
void *consumerS(void *param);

int serverCount=0;
int desktoprechnerCount=0;
int monitorCount=0;

int criticalSectionCountH=0;
int criticalSectionCountD=0;
int criticalSectionCountS=0;

int main()
{
  //semaphoren initialisieren
  pthread_mutex_init(&mutex, NULL);
  pthread_attr_init(&attr);
  sem_init(&server, 0, 0);
  sem_init(&desktoprechner, 0, 0);
  sem_init(&monitor, 0, 0);
  sem_init(&empty, 0, BUFFER_SIZE);
  
  //Threads erstellen
  pthread_create(&ptid, &attr, producerH, NULL);
  pthread_create(&dtid, &attr, consumerD, NULL);
  pthread_create(&stid, &attr, consumerS, NULL);
  //darauf warten, dass die Threads fertig sind
  pthread_join(ptid,NULL);
  pthread_join(dtid,NULL);
  pthread_join(stid,NULL);
  
  printf("%d mal im kritischen Bereich des Herstellers gewesen\n", criticalSectionCountH);
  printf("%d mal im kritischen Bereich des Techniker D gewesen\n", criticalSectionCountD);
  printf("%d mal im kritischen Bereich des Techniker S gewesen\n", criticalSectionCountS);

  return 0;
}


void *producerH(void *param)
{
  while(1)
  {
    int i;
    for(i=0;i<6;i++)
	sem_wait(&empty);
    pthread_mutex_lock(&mutex);
    criticalSectionCountH++;
    serverCount++;
    desktoprechnerCount = desktoprechnerCount + 3;
    monitorCount = monitorCount + 2;
    printf("%d Server entladen\n",serverCount);
    printf("%d desktoprechner entladen\n",desktoprechnerCount);
    printf("%d Monitore entladen\n",monitor);
    pthread_mutex_unlock(&mutex);
    sem_post(&server);
    sem_post(&desktoprechner);
    sem_post(&desktoprechner);
    sem_post(&desktoprechner);
    sem_post(&monitor);
    sem_post(&monitor);
  }
}

void *consumerD(void *param)
{
  while(1)
  {
    sem_wait(&desktoprechner);
    sem_wait(&monitor);
    pthread_mutex_lock(&mutex);
    criticalSectionCountD++;
    monitorCount--;
    desktoprechnerCount--;
    printf("%d desktoprechner beladen\n",desktoprechnerCount);
    printf("%d Monitore beladen\n",monitor);
    pthread_mutex_unlock(&mutex);
    sem_post(&empty);
    sem_post(&empty);
  }
}

void *consumerS(void *param)
{
  while(1)
  {
    sem_wait(&server);
    pthread_mutex_lock(&mutex);
    criticalSectionCountS++;
    serverCount--;
    printf("%d Server beladen\n",serverCount);
    pthread_mutex_unlock(&mutex);
    sem_post(&empty);
  }
}


Ist da vielleicht doch am Code was falsch oder muss ich es nur anders ausführen?
Ich kann mir jedenfalls nicht erklären, was am Code falsch sein könnte.
Vielen Dank im voraus.
Auf diesen Beitrag antworten »
deppensido

ich habe die Fehlermeldungen mal angehängt. Alle verweisen auf fehlende Referenzen, aber die sollten durch #include <pthread.h> und #include <semaphore.h> doch gegeben sein?
Auf diesen Beitrag antworten »
eulerscheZahl

Also, bei mir schluckt der Compiler das gcc blatt5.c -pthread (Ubuntu).

code:
1:
2:
3:
4:
5:
6:
7:
8:
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 
 
Auf diesen Beitrag antworten »
deppensido

danke,

bei mir klappt es jetzt auch. Ich musste über gcc -pthread Blatt5.c kompilieren, dann ist im Projektordner eine a.out Datei entstanden, die ich per Aktionen -> run in Konsole ausführen kann. Das ging also diesmal etwas anders als, wie ich es sonst gemacht hatte, daher die Probleme. Habe die Ausgaben noch etwas angepasst, sodass das Programm das gewünschte Verhalten ausgibt. Hier braucht also wohl nichts mehr verbessert werden. Scheint alles korrekt zu sein.
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »