Syncronisations Problem
-
Hallo Leute ich habe eine Problem meine Prozesse zu Syncronisieren.
Ich möchte folgendes erreichen
ein Prozess der auf meine Queue lesen und schreiben kann
eine unbestimmte anzahl von Prozessen die auf die Queue schreiben kann
desweiteren soll der Prozess der lesen und schreiben kann sollange warten
bis wieder was auf der Queue ist!!
dabei kann ich nur 2 Semaphoren verwenden!!ich habe ne Funktion
Lock(semid);
und eine Funktion
Unlock(semid);wie kriege ich das hin
ich stehe derzeitig voll auf dem Schlauch
-
Warum kann der eine lesen und schreiben?
-
Folgendes soll erreicht werden
Prozess(1..n)
push_data();//natürlich auch syncronisiertHauptProzess
read_data();
pop_data();und jetzt weiss ich leider nicht wie ich das syncronisieren soll
ich kann leider nur 2 Semaphoren verwenden
Bitte um hilfe
-
Ist die Aufgabenstellung irgendwie online?
-
Ist keine Aufgabenstellung für die Uni oder Schule, ist für ein privates Projekt
So ich versuche mich mal verständlicher auszudrücken
Ich will folgendes erreichen:
HauptProzess soll von einer Queue Daten lesen.
Solange keine Daten auf der Queue sind soll er warten.
Falls Daten auf die Queue geschrieben werden soll der Hauptprozess mit der Abarbeitung der Daten in der Queue beginnen.
Falls weitere Prozesse in der Zeit, in der der Hauptprozess die Daten liest auf die Queue schreiben will sollen diese Prozesse warten.Was ich aus Datenbanktechnischen Gründen leider nur machen kann sind 2 Semaphoren für diese Synchronisation zu verwenden.
-
Zunächst benötigst du einen Semaphor, um zu verhindern, daß sich die Prozesse gegenseitig unterbrechen - jeder Prozess reserviert ihn, wenn er arbeiten will, und gibt ihn am Ende wieder frei. Den zweiten Semaphor kannst du verwenden, um das leere-Liste-Problem zu lösen (obwohl da Events geeigneter wären) - die Schreib-Prozesse geben ihn jeweils frei, wenn sie fertig sind mit Einfügen, der Hauptprozess sperrt ihn und wartet dann auf die Freigabe, wenn er die Liste geleert hat.
-
So ich habe mir mal ein Programm dazu geschrieben
es Funktioniert nicht da irgendwie nur ein Prozess zum Printf kommt
und alle anderen warten brauche hilfe#include <sys/sem.h> #include <sys/ipc.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #define LOCK -1 #define UNLOCK 1 #define KEY1 123458L #define KEY2 123459L #define PERM 0666 int sem_id1; int sem_id2; static int init_semaphore (long key) { /* Testen ob das Semaphor bereits existiert */ int semid; semid = semget (key, 0, IPC_PRIVATE); if (semid < 0) { /* ... existiert noch nicht also anlegen */ /* Alle Zugriffsrechte der Dateikreierungsmaske erlauben */ umask(0); semid = semget (key, 1, IPC_CREAT | IPC_EXCL | PERM); if (semid < 0) { printf ("Fehler beim Anlegen des Semaphors ...\n"); return -1; } printf ("(angelegt) Semaphor-ID : %d\n", semid); /* Semaphor mit 1 initialisieren */ if (semctl (semid, 0, SETVAL, (int) 1) == -1) return -1; } return semid; } static int sem_op (int op,int sem) { static struct sembuf semaphore; semaphore.sem_op = op; semaphore.sem_flg = SEM_UNDO; if( semop (sem, &semaphore, 1) == -1) { perror(" semop "); printf("HALLO\n"); exit (EXIT_FAILURE); } return 1; } int main() { int a =0; sem_id1 =init_semaphore(KEY1); sem_id2 =init_semaphore(KEY2); if(fork== NULL) { sem_op(LOCK,sem_id1); printf("%d,push_dat\n",getpid()); sem_op(UNLOCK,sem_id1); sem_op(UNLOCK,sem_id2); } if(fork == NULL) { sem_op(LOCK,sem_id1); printf("%d,push_dat\n",getpid()); sem_op(UNLOCK,sem_id1); sem_op(UNLOCK,sem_id2); } if(fork == NULL) { sem_op(LOCK,sem_id1); printf("%d,push_dat\n",getpid()); sem_op(UNLOCK,sem_id1); sem_op(UNLOCK,sem_id2); } while(a <100) { sem_op(LOCK,sem_id1); sem_op(LOCK,sem_id2); printf("%d,read_data()\n",getpid()); sem_op(UNLOCK,sem_id1); a++; } semctl (sem_id1, 0, IPC_RMID, 0); semctl (sem_id2, 0, IPC_RMID, 0); return 0; }
-
Hier mal ein wenig pseudocode:
2 Semaphoren "datenVorhanden" und "datenLeer". "datenVorhanen" wird auf 0 initialisiert, "datenLeer" auf 1.
Leserprozess:
while(1) { semwait(datenVorhanden); // warte, daß die Semaphore 1 wird verarbeiteDaten(); sempost(datenLeer); // setze Sem auf 1 }
Schreiber:
while(1) { semwait(datenLeer); // warte, daß Semaphore 1 wird schreibeDaten(); sempost(datenVoranden); // melde Leser, daß Daten da sind }
Schreiberprozesse können beliebig viele vorhanden sein, da nur einer die Semaphore "datenLeer" dekrementieren kann.
Tntnet
-
Hallo habe immer noch das gleiche Problem ich hoffe ich die Vorgeschlagen Implementierung richtig hingekriegt
aber leider funktioniert das immer noch nicht
denn Mein Prog geht in kein printf rein#ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/types.h> #include <errno.h> #include <sys/sem.h> static struct sembuf semaphore; #define Lock -1 #define Unlock 1 long CreateKey(int a) { return ftok("/usr/include",a); } int pbCreateSemaphore(long key,int init) { static int a = 0; int sem_id; a++; sem_id = semget(CreateKey(a )+getpid(),1,IPC_PRIVATE); if (sem_id < 0) { umask(0); sem_id = semget(CreateKey( key)+getpid(),1,IPC_CREAT | IPC_EXCL | 0666); if(sem_id < 0) { printf("%s\n",strerror(errno)); return -1; } if(semctl(sem_id,0,SETVAL,(int)init)== -1) { printf("%s:\n",strerror(errno)); return -1; } } return sem_id; } void pbCloseSemaphore(int sem) { semctl(sem,0,IPC_RMID,0); } void pbSemaphoreOperation(int sem,int oper) { semaphore.sem_op = oper; semaphore.sem_flg = SEM_UNDO; if(semop(sem,&semaphore,1) == -1) { exit(-1); } } void semwait(int sem) { pbSemaphoreOperation(sem,Unlock); } void sempost(int sem) { pbSemaphoreOperation(sem,Unlock); } int main(int argc, char *argv[]) { int semid1; int semid2; int a = 0; semid1 = pbCreateSemaphore(777,0); semid2 = pbCreateSemaphore(888,1); if(fork == 0) { while(1) { pbSemaphoreOperation(semid2,Lock); printf("push_data:%d\n",getpid()); pbSemaphoreOperation(semid1,Unlock); pbSemaphoreOperation(semid2,Unlock); } } if(fork == 0) { while(1) { pbSemaphoreOperation(semid2,Lock); printf("push_data:%d\n",getpid()); pbSemaphoreOperation(semid1,Unlock); pbSemaphoreOperation(semid2,Unlock); } } if(fork == 0) { while(1) { pbSemaphoreOperation(semid2,Lock); printf("push_data:%d\n",getpid()); pbSemaphoreOperation(semid1,Unlock); } } while (a < 100) { pbSemaphoreOperation(semid1,Lock); pbSemaphoreOperation(semid2,Lock); printf("read_data:%d\n",getpid()); sleep(1); pbSemaphoreOperation(semid2,Unlock); a++; } pbCloseSemaphore(semid1); pbCloseSemaphore(semid2); return EXIT_SUCCESS; }
-
Ich weiß nicht, ob Du meine Antwort gelesen hast, aber es sieht nicht so aus. Dein Programm sieht mehr wie rumprobieren aus, bis es funktioniert, als wirklich verstehen.
Wobei mir auffällt, daß du gar keine Subprozesse startest. Der code:
if(fork == 0)
bewirkt, daß der Rumpf dann ausgeführt wird, wenn die Funktion fork ein Nullpointer ist. Das ist aber sich nicht der Fall. Du willst offensichtilch die Funktion fork aufrufen. Das macht man so:
if (fork())
Wobei Du damit noch keine Fehlerbehandlung hast. Fork könnte einen Fehlercode liefern. Den solltest Du auf jeden Fall abfragen.
Tntnet
-
Sorry ich bin ein Trottelkind
fork() ich weiss ich bin blöd meine Fresseich versuche es nochmal