Synchronisation mit Semaphoren

P

peerffm

Grünschnabel
hallo habe mich daran mal versucht.

vielleicht kann mirt jemand helfen.


Code:
#include <sys/ipc.h>
#include <sys/sem.h>


int main()
{
int semID;
struct sembuf sema;



//erzeuge des semaphoren
    semID = semget(25112, 1, IPC_CREAT | 0777);
    if (semID >= 0) {
        puts("Semaphore erzeugt.....");
        getchar();
//bereite vor und starte
        sema.sem_num = 0;
        sema.sem_flg = IPC_NOWAIT;
        sema.sem_op  = -1;
        if (-1==semop(semID, &sema, 1)) {
            
            perror("semop");
        }
        puts("huhu bin im kritischen Bereich");
        getchar();
        sema.sem_op  = 1;
        if (-1==semop(semID, &sema, 1)) {
            
            perror("semop");
        }
        puts("und nun wieder weg");
    } else {
        perror("semget");
    }
}

bekomme folgende ausgabe:
Semaphore erzeugt

semop: Ressource temporarily unavaible

huhu bin im kritischen bereich

und nun wieder weg

irgendwie funktioniert das nicht wenn ich mehrere Terminal Fenster öffne und es starte müsste er ja wenn ich mit dem einem im Kritischen Bereich bin denn anderen Blockieren.

und wieso bekomme ich die obere fehlermeldung.

kann mir da jemand helfen ? danke


peer
 
Vielleicht hilft diese Abfrage:
Code:
if ((semid = semget(25112, 1, 0666 | IPC_CREAT)) == -1) {
            perror("semget");
            exit(1);
        }

Ich bin auch Neuling in diesem Gebiet.
Vielleicht hilft dir der link:
http://www.pronix.de/pronix-219.html

Tschö
 
Hallo!

Der Link zum Openbook "Linux-Unix-Programmierung" ist ein guter Tipp und man kann eigentlich auf den Fehler kommen, wenn man der Beschreibung dort folgt:

1. Die Initialisierung der Semaphore fehlt. Nach dem
Code:
semID = semget(25112, 1, IPC_CREAT | 0777);
musst du die Semaphore mit einem Wert (z.B. 1) belegen:
Code:
/* Semaphor mit 1 initialisieren */
if (semctl (semid, 0, SETVAL, (int) 1) == -1) {
    perror("semctl");
}
Ansonsten kann
Code:
sema.sem_num = 0;
sema.sem_flg = IPC_NOWAIT;
sema.sem_op  = -1;
if (-1==semop(semID, &sema, 1)) {
    perror("semop");
}
nicht funktionieren, da der Wert der Semaphore nicht weiter erniedrigt werden kann.

2. Du musst außerdem prüfen ob die Semaphore schon existiert wenn du das Programm mehrmals startest, denn sonst initialisiert jeder Prozess die Semaphore mit einem positiven Wert und kommt somit in den kritischen Bereich.

Eine Möglichkeit wäre, die IF-Abfrage nach dem semget so umzustellen wie schon von heidler empfohlen und beim semget zusätzlich zu dem Flag IPC_CREAT noch IPC_EXCL anzugeben. Dann gibt semget auch -1 zurück wenn die Semaphore existiert und du könntest in der IF-Abfrage die Variable errno auf den Wert EEXIST prüfen (siehe semget manpage). In dem Fall das die Semaphore schon existiert müsstest du nur semget noch mal ohne IPC_CREAT und ohne IPC_EXCEL aufrufen um sie zu öffnen.

Beispiel:
Code:
/* Erzeuge Semaphor */
semID = semget(25112, 1, IPC_CREAT | IPC_EXCL | 0777);
if (semID == -1) {
    if (errno == EEXIST) {
        /* Öffne Semaphor */
        semID = semget(25112, 1, 0777);
        if (semID == -1) {
            perror("semget");
            exit(1);
        }
    }
    else {
        perror("semget");
        exit(1);
    }
}
else {
    /* Semaphor mit 1 initialisieren */
    if (semctl (semid, 0, SETVAL, (int) 1) == -1) {
        perror("semctl");
    }
}

Etwas übersichtlicher wird der Code wenn du dir Funktionen für das Erzeugen und Initialisieren der Semaphore und evtl. auch für die Operationen erhöhen und erniedrigen schreibst. Beispiele dazu gibts auch im Buch.

Gruß,
Philip
 
Zuletzt bearbeitet:
Hi,
wenn ich die sem_op = 0 setze und die semaphore mit dem wert 1 initialisiere
und dann folgedes ausführe;

Code:
struct sembuf op1  = {0, 0, 0};
struct sembuf op2 = {0, -1, 0};
int sema, kind1, kind2;
sema = semget(IPC_PRIVATE, 0, IPC_CREAT | 0777);
semctl(sema, 0, SETVAL, 1);

if((kind1 = fork()) == 0)
{
  semop(sema, 0, &op1, 1); //kind1 wartet weil semaphore den wert 1 hat
  exit(0);
}

if((kind2 = fork()) == 0)
{
  
  semop(sema, 0, &op2, 1);//kind2 läuft 
  exit(0);
}
kind 1 wuerde doch erst dann weiterlaufen, wenn die semaphore den wert 0 hat, oder?
kennst sich jemand mit der operation "sem_op = 0;" aus?
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

NagiosGrapher 1.7.1 funktioniert nicht

C HTTP request

dovecot und postfix Konfiguration Problem

Fehler beim Kompilieren von qcserial

Zurück
Oben