Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Softwaretechnik » Erzeuger/Verbraucher Problem in C » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Erzeuger/Verbraucher Problem in C
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
deppensido
Doppel-As


Dabei seit: 23.12.2012
Beiträge: 144

Erzeuger/Verbraucher Problem in C Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo,

ich soll mit Hilfe von POSIX Semaphoren das Erzeuger/Verbraucher Problem implementieren. Dabei soll jeweils ein Programm für Erzeuger und eines für Verbraucher erstellt werden.

Beim Erzeuger: Eine Semaphore soll erzeugt werden und in einer Schleifer (bis 100)
soll dann pro Sekunde der Wert der Semaphore erhöht und ausgegeben werden.
Das klappt soweit auch.

Beim Verzeuger: Die Semaphore vom Erzeuger soll geöffnet werden und in einer Schleife (bis 10) soll die Semaphore jeweils dekrementiert und ausgegeben werden.
Hier kommt: Speicherzugriffsfehler.

Ich habe keine Ahnung was ich falsch mache, wäre schön wenn jemand drüber schauen könnte.
Anbei die Programm-Codes:

Erzeuger:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

sem_t sem;

int main() {
    sem_init(&sem, 0, 0);
    int value; 
    for(int i=0; i < 100; i++) {
        sleep(1);
        sem_post(&sem);
        sem_getvalue(&sem, &value); 
        printf("The value of the semaphore is %d\n", value);
    }

    sem_destroy(&sem);
    return 0;
}

Verbraucher:
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:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h> 
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>

int main() {
    int value;
    sem_t *mySem = sem_open("sem",  O_CREAT|O_EXCL , S_IRUSR|S_IWUSR , 0); 

    for(int i=0; i < 10; i++) {
        sem_wait(mySem);
        sem_getvalue(mySem, &value); 
        printf("The value of the semaphore is %d\n", value);
    }
    sem_close(mySem);
    sem_unlink("sem");
    return 0;
}
15.06.2018 00:04 deppensido ist offline Beiträge von deppensido suchen Nehmen Sie deppensido in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 639
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ich hab das bisher selbst noch nie verwendet, aber nach der Doku, die ich gefunden habe, musst Du Dich zuerst entscheiden, ob es ein named semaphore sein soll oder nicht (soll es sein, würde ich sagen) und wenn ja, dann fangen die Namen wohl immer mit einem / an. Du musst dann aber in beiden Prozessen ein sem_open mit demselben Namen verwenden, woher sollen die sonst wissen, dass sie sich auf dasselbe beziehen sollen?

Sonst müsste ich das selbst erst ausprobieren.

Gruß
Marco
16.06.2018 09:01 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 639
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ich hab mir das noch etwas genauer angeschaut.
Erstens musst Du Dich entscheiden, ob Du named semaphores verwenden willst, oder nicht. Wenn sie nicht named sein sollen, Du aber trotzdem von verschiedenen Prozessen drauf zugreifen willst, dann musst Du die Semaphore in einem shared memory segment o. ä. ablegen, das Du vorher noch anlegen musst und so weiter. Das ist viel mehr Aufwand und lohnt sich mE nur, wenn man in diesem shared memory segment noch andere Daten ablegen will.
Wenn Du named verwendest, dann müssen die Namen immer mit einem "/" anfangen. Du machst beim Producer (Erzeuger) ein sem_open mit 4 Argumenten und am Ende ein sem_close und auch ein sem_unlink. Das sem_unlink löscht das Semaphore derart aus dem System, dass ein Prozess, der sich neu mit diesem verbinden will (mit sem_open) das nicht mehr findet. Allerdings laufen alle Prozesse, die sich schon vorher damit verbunden haben, weiter und halten die Semaphore auch noch offen.
Man kann also ein sem_open machen, alle Prozesse starten, die sich mit sem_open an dieselbe Semaphore hängen und sobald diese ihr sem_open gemacht haben, kann irgendein Prozess ein sem_unlink machen. Wenn danach alle verwendenden Prozesse ein sem_close aufgerufen haben, ist die Semaphore auch weg.
Das sem_init und was weiß ich, was Du noch hattest, braucht man nur für unnamed semaphores, so wie ich das verstanden habe.

Bei mir sieht der producer.c dann so aus:
php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h> 


int main() {
    sem_t *sem sem_open("/sem",  O_CREAT S_IRUSR|S_IWUSR 0); 
    if (sem == SEM_FAILED) {
        perror("sem_open(3) error");
        exit(EXIT_FAILURE);
    }
    int value; 
    for(int i=0100i++) {
        sleep(1);
        sem_post(sem);
        sem_getvalue(sem, &value); 
        printf("The value of the semaphore is %d\n"value);
    }
    sem_close(sem);    
    sem_unlink("/sem");
    return 0;
}


und der consumer.c so:

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h> 

int main() {
    int value;
    sem_t *sem sem_open("/sem",  O_RDWR); 
    if (sem == SEM_FAILED) {
        perror("sem_open(3) error");
        exit(EXIT_FAILURE);
    }
    
    for(int i=010i++) {
        sem_wait(sem);
        sem_getvalue(sem, &value); 
        printf("The value of the semaphore is %d\n"value);
    }
    sem_close(sem);
    return 0;
}


Compilieren kann ich das unter Linux mit
code:
1:
2:
gcc -lrt -lpthread producer.c -o producer;
gcc -lrt -lpthread consumer.c -o consumer


Man muss dann erst den producer-Prozess starten und später dann ein oder mehrmals den consumer.

Gruß
Marco
16.06.2018 20:10 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Softwaretechnik » Erzeuger/Verbraucher Problem in C