Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Prüfungen im Bachelor-Studium (1. - 5. Semester) » Lösungsvorschlag (Übersicht)
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
pruefungen:bachelor:2014s-sp-klausur-loesung [28.07.2015 15:07] – angelegt Anola | pruefungen:bachelor:2014s-sp-klausur-loesung [28.07.2015 15:13] (aktuell) – Anola | ||
---|---|---|---|
Zeile 103: | Zeile 103: | ||
} | } | ||
| | ||
- | struct data *video = malloc (sizeof(struct data));//warum mallocen und net aufm stack anlegen | + | struct data *video = malloc (sizeof(struct data)); |
| | ||
// Videobilder einlesen und in den Puffer schreiben | // Videobilder einlesen und in den Puffer schreiben | ||
| | ||
size_t bytesRead = 0; | size_t bytesRead = 0; | ||
- | while((bytesRead = fread(video-> | + | while((bytesRead = fread(video-> |
| | ||
- | if(bytesRead < 307200){//braucht man hier net eher feof() und kann die byte anzahl einfach untern tisch kehren^^// | + | if(bytesRead < 307200){ |
- | + | ||
- | video-> | + | |
+ | video-> | ||
}else{ | }else{ | ||
Zeile 125: | Zeile 124: | ||
jbPut(video); | jbPut(video); | ||
- | //wenn mit malloc fehlt free, jbPut/Get kopiert den Inhalt, nicht den pointer | + | |
- | video = malloc (sizeof(struct data));//warum?, stack sollte reichen | + | video = malloc (sizeof(struct data)); |
| | ||
Zeile 134: | Zeile 133: | ||
| | ||
- | errno = phtread_join(tid, | + | errno = phtread_join(tid, |
| | ||
if(errno != 0){ | if(errno != 0){ | ||
Zeile 149: | Zeile 148: | ||
} | } | ||
| | ||
- | exit(EXIT_FAILURE); | + | exit(EXIT_FAILURE); |
} | } | ||
// Ende Funktion main | // Ende Funktion main | ||
Zeile 155: | Zeile 154: | ||
// Ausgabegeräte suchen | // Ausgabegeräte suchen | ||
| | ||
- | void * showFrame(void){//hat übergabeparameter void , verträgt sich also nicht mit der pthread_create funktion weil die erwartet ein void * -> | + | void * showFrame(void){ |
- | | + | |
DIR *d; | DIR *d; | ||
if((dir = opendir("/ | if((dir = opendir("/ | ||
Zeile 168: | Zeile 166: | ||
FILE * outFiles[10]; | FILE * outFiles[10]; | ||
| | ||
- | while((e= readdir(d)) != NULL && nFiles < 10 ){ //ich haette hier eher ne for-Schleife gemacht | + | while((e= readdir(d)) != NULL && nFiles < 10 ){ |
| | ||
if(fnmatch( " | if(fnmatch( " | ||
| | ||
/ | / | ||
- | char path[strlen("/ | + | char path[strlen("/ |
sprintf(path, | sprintf(path, | ||
| | ||
- | outFiles[nFiles] = fopen(path, " | + | outFiles[nFiles] = fopen(path, " |
- | // das Arbeitsverzeichnis ist ja nicth in /dev von daher muss man denke ich schon den absoluten pfad angeben, weil der relative bezieht sich ja aufs Arbeitsverzeichnis und des kann irgendwo sein, oder? | + | |
- | | + | |
- | | + | |
if(outFiles[nFiles] == NULL){ | if(outFiles[nFiles] == NULL){ | ||
perror(" | perror(" | ||
Zeile 190: | Zeile 186: | ||
| | ||
| | ||
- | // Videobilder aus Puffer entnehmen und ausgeben | + | |
struct data *video; | struct data *video; | ||
| | ||
Zeile 199: | Zeile 195: | ||
| | ||
for(int i = 0; i < nFiles; i++){ | for(int i = 0; i < nFiles; i++){ | ||
- | fwrite(video-> | + | fwrite(video-> |
} | } | ||
| | ||
eof = video-> | eof = video-> | ||
- | free(video)// | + | free(video); |
if(fclose(outFiles[i]) == EOF){ | if(fclose(outFiles[i]) == EOF){ | ||
die(" | die(" | ||
Zeile 233: | Zeile 229: | ||
| | ||
if(waiter == NULL || fullSlots == NULL || freeSlots == NULL){ | if(waiter == NULL || fullSlots == NULL || freeSlots == NULL){ | ||
- | frpintf(" | + | frpintf(" |
semDestroy(waiter); | semDestroy(waiter); | ||
semDestroy(fullSlots); | semDestroy(fullSlots); | ||
semDestroy(freeSlots); | semDestroy(freeSlots); | ||
return 1; | return 1; | ||
- | } //Annahme: semDestroy(NULL) tut nichts// | + | } |
itemsBuffered = readPos = writePos = 0;//ist schon implizit auf 0 | itemsBuffered = readPos = writePos = 0;//ist schon implizit auf 0 | ||
return 0; | return 0; | ||
} | } | ||
// Funktion jbPut | // Funktion jbPut | ||
- | void jbPut(const struct data *data){//returnen und nicht einfach Blockieren? //war schon ein P, ein P wie Plockieren und ein V wie Vreigeben, | + | void jbPut(const struct data *data){ |
if(itemsBuffered >= CACHE_SIZE) | if(itemsBuffered >= CACHE_SIZE) | ||
- | return; | + | return; |
| | ||
P(freeSlots); | P(freeSlots); | ||
- | cache[writePos] = data; //Sollte hier bzw weiter unten nicht stehen: cache[writePos] = *data; ? Das Array speichert Structs und nicht pointer. geht das so, oder braucht man memcpy?. | + | cache[writePos] = data; cache[writePos++] = data; |
- | //sollte ohne memcpy gehen. Siehe Rudis kommentar im thread zu der aufgabe im forum//wo steht der kommentar?// | + | |
- | // | + | |
- | //letzter kommentar in den thread.// ja da steht genau des mit dem = (ich glaube rudi meint, dass das structs kopieren über diese = operation schon seit C89 geht oder aber memcpy????, bin mir da net ganz sicher was er meint, aber = geht aufjedenfall) | + | |
- | // = sollte gehen für structs, joa//bei was braucht man eigentlich memcpy überhaupt? realloc implementieren :D ne, memcpy is für zeug aufm heap glaub ich.//naja heap kann ich auch derefernzieren und mit = vollschreiben// | + | |
- | //hm stimmt, müsste derefenziert werden der pointer, habs zwar jetzt hier nicht getestet, aber sollte schon so sein | + | |
- | //ok net ganz richtig für arrays mit variabler länge gilt das nicht da sinds ja nur pointer und da werden pointeradressen einfach kopiert und nicht mehr | + | |
- | // | + | |
| | ||
- | // writepos wieder auf 0 setzen? | + | |
- | // if(writePos >= CACHE_SIZE) writePos = 0; | + | |
| | ||
V(fullSlots); | V(fullSlots); | ||
itemsBuffered++; | itemsBuffered++; | ||
- | if(itemsBuffered == BUFFER_SIZE){//ah cool, glaube da wäre ich wirklich net so schnell drauf gekommen des so zu lösen | + | if(itemsBuffered == BUFFER_SIZE){ |
V(waiter); | V(waiter); | ||
} | } | ||
| | ||
- | + | Slots | |
- | //ICH BIN MIR NICHT SICHER ob die Sache mit von Puffer auf Durchzug schalten hier wirklich korrekt ist. Ich habe das so geloest: in der init-Funktion den waiter auf minus 20 setzen, dann muss 20 mal V(waiter) aufgerufen werden, in Flush mache ich auf waiter noch mal semCreate mit 0. Dann ist der Spuk vorbei. | + | |
- | [//Ich rufe also immer in put V(waiter) und in get P(waiter) auf also genauso wie fullSlots | + | |
} | } | ||
// Funktion jbGet | // Funktion jbGet | ||
Zeile 279: | Zeile 265: | ||
| | ||
//readPos ++; | //readPos ++; | ||
- | | + | |
struct data dat = cache[readPos++]; | struct data dat = cache[readPos++]; | ||
- | itemsBuffered--; | + | itemsBuffered--; |
- | + | ||
- | //das stimmt, aber in itemsBuffered sollte ja die zahl der Elemente im cache stehen oder nicht? | + | |
- | + | ||
- | //naja gut, wenn man davon ausgeht, dass man die zahl nie mehr braucht, kann mans auch weglassen. | + | |
- | + | ||
- | //ansonsten ist mir das problem schon aufgefallen. Man müsste dann noch in der put funktion prüfen, ob das bereits einmal aktiviert wurde. | + | |
- | + | ||
- | //Das gleiche Problem kriegt man aber auch simpler: 2 mal Flushen.... wobei das hier nicht unser problem wäre. | + | |
- | + | ||
- | //evtl sollte man dann generell überall wo man V(waiter) macht schauen, ob das schonmal getan wurde. Dann fixt man es für alles gleichzeitig | + | |
+ | | ||
data = & | data = & | ||
if(readPos >= CACHE_SIZE) readPos = 0; | if(readPos >= CACHE_SIZE) readPos = 0; | ||
- | */ | + | |
| | ||
V(freeSlots); | V(freeSlots); |