//16:35 Wallertheim //Michael Richner 661904 //BS1 UEbung 6 #include #include #include #include #include #include #include #include #include #define RED "\033[22;31m" #define NORMAL "\033[00m" #define LIGHT_BLUE "\033[01;34m" #define YELLOW "\033[01;33m" #define LIGHT_MAGENTA "\033[01;35m" #define LOCK +1 //P #define UNLOCK -1 //V #define WAIT 0 #define PERM 0700 /* Zugriffsrechte */ #define KEY 661904 #define ANZAHL 8 /*Anzahl der Semaphore*/ struct daten{ int prozesse[4]; float vektor_1[5]; float vektor_2[5]; float ergebnis[6]; }; struct daten* shmid_init(int *shmid, struct daten *shm); struct daten* shm_init(struct daten *shm); int shm_dell(); static int init_semaphore(); static int semaphore_operation (int num, int op); int sem_dell(int sem); int einlesen_Zahl(struct daten *shm, int prozess); int addition(struct daten *shm); int multiplikation(struct daten* shm); static struct sembuf semaphore; static int semID; int main(int argc, char ** argv){ struct daten *shm; //Alle benötigte Werte für die Steuerung (Zeiger auf das Segment. int i = 0; int temp = 0; shm = shm_init(shm); int res = init_semaphore(); if (res < 0) return EXIT_FAILURE; while (optind < argc){ int result = getopt(argc, argv, "aemh"); if (result == -1) break; /* end of list */ switch (result){ case 'h': //help printf("'h' was specified.\n"); break; case 'a': //addition printf("'a' was specified.\n"); if(shm->prozesse[0] == 0){ shm->prozesse[0] = 1; addition(shm); shm->prozesse[0] = 0; }else{ printf("%sFehler, es exestiert schon der Additions Prozesse!%s\n", RED, NORMAL); } break; case 'm': //multiplikation printf("'m' was specified.\n"); if(shm->prozesse[3] == 0){ shm->prozesse[3] = 1; multiplikation(shm); shm->prozesse[3] = 0; }else{ printf("%sFehler, es exestiert schon der Multiplikations Prozesse!%s\n", RED, NORMAL); } break; case 'e': //eingabe printf("'e' was specified.\n"); if(shm->prozesse[1] == 0){ shm->prozesse[1] = 1; einlesen_Zahl(shm, 0); shm->prozesse[1] = 0; }else if(shm->prozesse[2] == 0) { shm->prozesse[2] = 1; einlesen_Zahl(shm, 1); shm->prozesse[2] = 0; }else{ printf("%sFehler, es exestiert schon zwei Eingabe Prozesse!%s\n", RED, NORMAL); } break; default: /* unknown */ printf("%sError; kenne <%s> als Option nicht!%s\n", RED, argv[optind++], NORMAL); break; } } while (optind < argc) { printf("%sError; kenne <%s> als Option nicht!%s\n", RED, argv[optind++], NORMAL); } temp = 0; for(i=0;i<4;i++){ if(shm->prozesse[i] == 1){ temp = temp + 1; } } if(temp == 1){ for(i=1;i= 0){ printf("\t%sSEM gelöscht%s\n", LIGHT_BLUE, NORMAL); }else{ printf("\t%sFehler beim löschen der SEM!%s\n", RED, NORMAL); } } if(shm_dell() >= 0){ printf("\t%sSHM gelöscht%s\n", LIGHT_BLUE, NORMAL); }else{ printf("\t%sFehler beim löschen des SHM!%s\n", RED, NORMAL); } } return 0; } int multiplikation(struct daten* shm){ int i = 0; int temp = 0; printf("%sMultiplikations Prozess\n%s", YELLOW, NORMAL); do{ semaphore_operation(5, WAIT); semaphore_operation(5, LOCK); semaphore_operation(6, WAIT); semaphore_operation(6, LOCK); for(i=0;i<5;i++){ temp = temp + shm->vektor_1[i] * shm->vektor_2[i]; } shm->ergebnis[5] = temp; printf("Ergbnis[5] = %f\n", shm->ergebnis[5]); printf("%s---\n%s", YELLOW, NORMAL); semaphore_operation(8, UNLOCK); }while(shm->prozesse[1] == 1 && shm->prozesse[2] == 1); return 1; } int addition(struct daten* shm){ int i = 0; printf("%sAdditions Prozess\n%s", YELLOW, NORMAL); do{ semaphore_operation(3, WAIT); semaphore_operation(3, LOCK); semaphore_operation(4, WAIT); semaphore_operation(4, LOCK); for(i=0;i<5;i++){ shm->ergebnis[i] = shm->vektor_1[i] + shm->vektor_2[i]; } for(i=0;i<5;i++){ printf("Ergebnis[%i] = %f\n",i,shm->ergebnis[i]); } printf("%s---\n%s", YELLOW, NORMAL); semaphore_operation(7, UNLOCK); }while(shm->prozesse[1] == 1 && shm->prozesse[2] == 1); return 1; } int einlesen_Zahl(struct daten* shm, int prozess){ int eingabe_z = 0; //fürs einlesen der Zahl char eingabe_r = 0; //fürs einlesen Y oder N bool abbruch_1 = false; //für schleife zahl eingabe bool abbruch_2 = false; //für schleife programm abbruch eingabe int ergebnis = 0; //eingabe überprüfung int i = 0; if(prozess == 0){ printf("%sEingabe Prozess %i\n%s", YELLOW, prozess+1, NORMAL); }else{ printf("%sEingabe Prozess %i\n%s", YELLOW, prozess+1, NORMAL); } //Schleife für die dauerhafte Eingabe while(abbruch_1 == false){ abbruch_2 = false; if(prozess == 0){ semaphore_operation(1, WAIT); semaphore_operation(1, LOCK); }else if(prozess == 1){ semaphore_operation(2, WAIT); semaphore_operation(2, LOCK); } for(i=0;i<5;i++){ do{ printf("%sBitte geben Sie die %ite Zahl ein: %s", YELLOW, i+1, NORMAL); ergebnis = scanf("%i", &eingabe_z); if(ergebnis != 1){ printf("%sFehler, Ihrer Eingabe war keine Gültige Zahl!%s\n",RED ,NORMAL); }else{ if(prozess == 0){ //eingabe 1 shm->vektor_1[i] = eingabe_z; }else{ shm->vektor_2[i] = eingabe_z; } printf("\t%sschreibe Vektor[%i] = %s%i%s\n",LIGHT_BLUE, i, LIGHT_MAGENTA, eingabe_z, YELLOW); } }while(getchar() != '\n'); } while(abbruch_2 == false){ printf("%sMöchten Sie eine neue Zahl eingeben? [%sY%s = Yes\\%sN%s = No]: %s", YELLOW, LIGHT_MAGENTA, YELLOW, LIGHT_MAGENTA, YELLOW, NORMAL); ergebnis = scanf("%s", &eingabe_r); if(ergebnis == 1){ if(eingabe_r == 'y' || eingabe_r == 'Y') { abbruch_2 = true; if(prozess == 0){ //eingabe 1 semaphore_operation(3, UNLOCK); semaphore_operation(5, UNLOCK); }else{ semaphore_operation(4, UNLOCK); semaphore_operation(6, UNLOCK); } }else if(eingabe_r == 'n' || eingabe_r == 'N') { abbruch_1 = true; abbruch_2 = true; if(prozess == 0){ //eingabe 1 semaphore_operation(3, UNLOCK); semaphore_operation(5, UNLOCK); }else{ semaphore_operation(4, UNLOCK); semaphore_operation(6, UNLOCK); } }else{ printf("%sFehler, beim einlesen des Zeichens! Bitte nur Y oder N eingeben%s\n",RED ,NORMAL); } }else{ printf("%sFehler, beim einlesen des Zeichens!%s\n",RED ,NORMAL); } } semaphore_operation(7, WAIT); semaphore_operation(7, LOCK); semaphore_operation(8, WAIT); semaphore_operation(8, LOCK); for(i=0;i<6;i++){ printf("Ergebnis[%i] = %f\n",i,shm->ergebnis[i]); } semaphore_operation(1, UNLOCK); semaphore_operation(2, UNLOCK); } return 1; } //*** für initialiesieren/anbinden & löschen des SEM *** //Zum Initialiesieren der SEM static int init_semaphore(){ /* Testen ob das Semaphor bereits existiert */ semID = semget (KEY, ANZAHL, IPC_CREAT | IPC_EXCL | PERM); if (semID < 0) { /* ... existiert noch nicht also anlegen */ /* Alle Zugriffsrechte der Dateikreierungsmaske erlauben */ semID = semget (KEY, ANZAHL, IPC_CREAT | PERM); if (semID < 0) { printf("\t%sFehler beim Anlegen des Semaphors ...%s\n", RED, NORMAL); return -1; } printf ("\t%s(angelegt) Semaphor-ID : %d%s\n", LIGHT_BLUE, semID, NORMAL); /* Semaphor mit 1 initialisieren */ if (semctl (semID, 0, SETVAL, (int) 1) == -1) return -1; }else{ printf("\t%sSEM vorhanden ermittle ID%s\n", LIGHT_BLUE, NORMAL); } return 1; } //Lock oder Unlock die Semaphore static int semaphore_operation(int num, int op){ num=num-1; semaphore.sem_num = num; semaphore.sem_op = op; semaphore.sem_flg = SEM_UNDO; if(op == WAIT){ printf("\tWAIT (S%i)\n", num); }else if(op == LOCK){ printf("\tP(S%i)\n", num); }else if(op == UNLOCK){ printf("\tV(S%i)\n", num); } if( semop (semID, &semaphore, 1) == -1) { printf("num: %i, op: %i, semID: %i\n",num,op,semID); perror(" semop "); exit (EXIT_FAILURE); } return 1; } //Löscht SEM int sem_dell(int sem){ int semID = semget(KEY, ANZAHL, IPC_CREAT|0700); if (semID >= 0) { /* zerstöre die Semaphore */ semctl(semID, sem, IPC_RMID, 0); return 1; } else { /* semctl lief schief */ printf("\t%sFehler beim Löschen des SHM!%s\n", RED, NORMAL); return -1; } } //*** für initialiesieren/anbinden & löschen des SHM *** //SHM anbinden struct daten* shmid_init(int *shmid, struct daten* shm){ //Bindet Shared-Memory-Bereich bei sich ein: shm zeigt dann auf den Anfang des Bereichs shm = (struct daten *) shmat(*shmid, 0, 0); if(&shm != NULL){ printf("\t%sSHM verbunden%s\n", LIGHT_BLUE, NORMAL); }else{ //Error printf("\t%sFehler beim anbinden des SHM!%s\n", RED, NORMAL); shmctl(*shmid,IPC_RMID,0); //loeschen des Shared-Memory-Segment exit(-1); } return shm; } //Zum Initialiesieren der SHM struct daten* shm_init(struct daten* shm){ int shmid; // Identifikator des Shared-Memory-Segments key_t key = 661904; //Key für das SHM //Erzeugung eines Shared-Memory-Segments zur Aufnahme der Werten shmid = shmget(key, sizeof(struct daten), IPC_CREAT|IPC_EXCL|0700); if(shmid == -1){ //SHM ist schon vorhanden shmid = shmget(key, sizeof(struct daten), IPC_CREAT|0700); if(shmid != -1){ printf("\t%sSHM vorhanden ermittle ID%s\n", LIGHT_BLUE, NORMAL); shm = shmid_init(&shmid, shm); }else{ //Error printf("\t%sFehler beim Erstellen des SHM!%s\n", RED, NORMAL); shmctl(shmid,IPC_RMID,0); //loeschen des Shared-Memory-Segment exit(-1); } }else{ printf ("\t%s(angelegt) SeHM-ID : %d%s\n", LIGHT_BLUE, shmid, NORMAL); //printf("%sSHM erstellt%s\n", LIGHT_BLUE, NORMAL); shm = shmid_init(&shmid, shm); } return shm; } //Löscht SHM int shm_dell(){ key_t key = 661904; //Key für das SHM int shmid = shmget(key, sizeof(struct daten), IPC_CREAT|0700); if(shmid != -1){ //wenn vorhanden return shmctl(shmid,IPC_RMID,0); //loeschen des Shared-Memory-Segment; }else{ //Error printf("\t%sFehler beim Löschen des SHM!%s\n", RED, NORMAL); return -1; } }