Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Prüfungen im Bachelor-Studium (1. - 5. Semester) » Lösungsvorschlag
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung | Letzte ÜberarbeitungBeide Seiten, nächste Überarbeitung | ||
pruefungen:bachelor:2013w-sp-klausur-loesung [14.02.2016 19:05] – ThiloK | pruefungen:bachelor:2013w-sp-klausur-loesung [14.02.2016 19:07] – ThiloK | ||
---|---|---|---|
Zeile 20: | Zeile 20: | ||
**a)** | **a)** | ||
+ | <code cpp> | ||
+ | /* Klausur Februar 2014 - Aufgabe 2: mops */ | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // weitere Includes, Konstanten | ||
+ | // globale Variablen, Funktionsdeklarationen usw. | ||
+ | |||
+ | #define BUFFER_SIZE 64 | ||
+ | |||
+ | unsigned int spawnThreads(void); | ||
+ | void *feedPrinter(const char*); | ||
+ | SEM *semCreate(int); | ||
+ | void P(SEM *); | ||
+ | void V(SEM *); | ||
+ | |||
+ | struct SEM { | ||
+ | volatile int val; | ||
+ | pthread_mutex_t m; | ||
+ | pthread_cond_t c; | ||
+ | }; | ||
+ | |||
+ | static int port; | ||
+ | static int buffer[BUFFER_SIZE]; | ||
+ | static int in, out; | ||
+ | static SEM *inSem, *outSem; | ||
+ | |||
+ | static void die(const char message[]) { | ||
+ | perror(message); | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | unsigned int printer; | ||
+ | int sock; | ||
+ | struct sockaddr_in6 addr; | ||
+ | |||
+ | if (argv != 2) { | ||
+ | fprintf(stderr, | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | if ((inSem = semCreate(BUFFER_SIZE)) == NULL) | ||
+ | die(" | ||
+ | |||
+ | if ((outSem = semCreate(0)) == NULL) | ||
+ | die(" | ||
+ | |||
+ | port = (int) strtol(argv[1]); | ||
+ | |||
+ | printer = spawnThreads(); | ||
+ | if (printer < 0) | ||
+ | die(" | ||
+ | |||
+ | printf(" | ||
+ | if (printer == 0) | ||
+ | return 0; | ||
+ | |||
+ | sock = socket(AF_INET6, | ||
+ | if (sock < 0) | ||
+ | die(" | ||
+ | |||
+ | addr = { | ||
+ | .sin6_family = AF_INET6, | ||
+ | .sin6_port = htons(port), | ||
+ | .sin6_addr = in6addr_any, | ||
+ | }; | ||
+ | |||
+ | if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) | ||
+ | die(" | ||
+ | if (listen(sock, | ||
+ | die(" | ||
+ | |||
+ | for (;;) { | ||
+ | int clientSock = accept(sock, | ||
+ | if (clientSock < 0) | ||
+ | continue; | ||
+ | P(inSem); | ||
+ | buffer[in] = clientSock; | ||
+ | in = (in + 1) % BUFFER_SIZE | ||
+ | V(outSem); | ||
+ | } | ||
+ | close(sock); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | unsigned int spawnThreads() { | ||
+ | unsigned int numb; | ||
+ | DIR *dir = opendir("/ | ||
+ | if (dir == NULL) | ||
+ | return numb; | ||
+ | struct dirent *ent; | ||
+ | while (errno = 0, (ent = readdir(dir)) != NULL) { | ||
+ | if (ent-> | ||
+ | char path[6 + strlen(ent-> | ||
+ | snprintf(path, | ||
+ | struct stat s; | ||
+ | if (lstat(path, | ||
+ | return 0; | ||
+ | if (S_ISREG(s.st_mode)) { | ||
+ | if (pthread_create(NULL, | ||
+ | return 0; | ||
+ | numb++; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if (errno != 0) | ||
+ | return 0; | ||
+ | return numb; | ||
+ | } | ||
+ | |||
+ | void *feedPrinter(const char device[]) { | ||
+ | FILE *dev = fopen(device, | ||
+ | if (dev == NULL) { | ||
+ | return; | ||
+ | } | ||
+ | for (;;) { | ||
+ | int sock; | ||
+ | P(outSem); | ||
+ | do { | ||
+ | sock = buffer[out]; | ||
+ | out = (out + 1) % BUFFER_SIZE; | ||
+ | } while (__sync_compare_and_swap(buffer[out], | ||
+ | V(inSem); | ||
+ | FILE *req; | ||
+ | if ((req = fdopen(sock, | ||
+ | continue; | ||
+ | int c; | ||
+ | while ((c = fgetc(req)) != EOF) | ||
+ | fputc(c, dev); | ||
+ | close(sock); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | SEM *semCreate(int initial_value) { | ||
+ | struct SEM sem = { | ||
+ | .val = initial_value | ||
+ | } | ||
+ | errno = 0; | ||
+ | if ((errno = pthread_mutex_init(sem.m, | ||
+ | return NULL; | ||
+ | if ((errno = pthread_cond_init(sem.c, | ||
+ | return NULL; | ||
+ | return &sem; | ||
+ | } | ||
+ | |||
+ | void P(SEM *sem) { | ||
+ | if ((errno = pthread_mutex_lock(& | ||
+ | return; | ||
+ | while (sem-> | ||
+ | if ((errno = pthread_cond_wait(& | ||
+ | pthread_mutex_unlock(& | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | sem-> | ||
+ | if ((errno = pthread_mutex_unlock(& | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | void V(SEM *sem) { | ||
+ | if ((errno = pthread_mutex_lock(& | ||
+ | return; | ||
+ | sem-> | ||
+ | if ((errno = pthread_cond_broadcast(& | ||
+ | return; | ||
+ | if ((errno = pthread_mutex_unlock(& | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | </ | ||
==== Aufgabe 3: ==== | ==== Aufgabe 3: ==== | ||
Zeile 91: | Zeile 270: | ||
8. Prozess geht in Zustand bereit ueber | 8. Prozess geht in Zustand bereit ueber | ||
9. Befehl der den Trap ausgeloest hat wird wiederholt | 9. Befehl der den Trap ausgeloest hat wird wiederholt | ||
- | |||