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 7 /*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(4, WAIT);
semaphore_operation(4, 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(6, 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(2, WAIT);
semaphore_operation(2, LOCK);
semaphore_operation(3, WAIT);
semaphore_operation(3, LOCK);
semaphore_operation(4, UNLOCK);
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(5, 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;
//int temp = 0; //0 = Eingabe 1 / 1 = Eingabe 2
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(0, WAIT);
semaphore_operation(0, LOCK);
}else{
semaphore_operation(1, WAIT);
semaphore_operation(1, 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(2, UNLOCK);
semaphore_operation(5, WAIT);
semaphore_operation(5, LOCK);
semaphore_operation(6, WAIT);
semaphore_operation(6, LOCK);
}else{
semaphore_operation(3, UNLOCK);
}
}else if(eingabe_r == 'n' || eingabe_r == 'N') {
abbruch_1 = true;
abbruch_2 = true;
if(prozess == 0){ //eingabe 1
semaphore_operation(2, UNLOCK);
semaphore_operation(5, WAIT);
semaphore_operation(5, LOCK);
semaphore_operation(6, WAIT);
semaphore_operation(6, LOCK);
}else{
semaphore_operation(3, 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);
}
}
for(i=0;i<6;i++){
printf("Ergebnis[%i] = %f\n",i,shm->ergebnis[i]);
}
semaphore_operation(0, UNLOCK);
semaphore_operation(1, 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){
semaphore.sem_num = num;
semaphore.sem_op = op;
semaphore.sem_flg = SEM_UNDO;
if(op == WAIT){
printf("\tWAIT (S%i)\n", num+1);
}else if(op == LOCK){
printf("\tP(S%i)\n", num+1);
}else if(op == UNLOCK){
printf("\tV(S%i)\n", num+1);
}
if( semop (semID, &semaphore, num) == -1) {
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;
}
}