All pastes #802012 Raw Edit

Vermischtes

public text v1 · immutable
#802012 ·published 2007-11-29 21:21 UTC
rendered paste body
//16:35 Wallertheim

//Michael Richner 661904
//BS1 UEbung 6

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdbool.h>

#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<ANZAHL;i++){
			if(sem_dell(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, 0, IPC_PRIVATE);
	if (semID < 0) {
		/* ... existiert noch nicht also anlegen */
		/* Alle Zugriffsrechte der Dateikreierungsmaske erlauben */
		semID = semget (KEY, ANZAHL, IPC_CREAT | IPC_EXCL | 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;
	}	
}