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.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Letzte ÜberarbeitungBeide Seiten, nächste Überarbeitung
pruefungen:bachelor:2013w-sp-klausur-loesung [14.02.2016 19:05] ThiloKpruefungen: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 <dirent.h>
 +#include <errno.h> 
 +#include <pthread.h> 
 +#include <stdio.h> 
 +#include <stdlib.h> 
 +#include <string.h> 
 +#include <netinet/in.h> 
 +#include <sys/socket.h> 
 +#include <sys/stat.h>
 +
 +// 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, "usage: ./mops port\n");
 + return 0;
 + }
 +
 + if ((inSem = semCreate(BUFFER_SIZE)) == NULL)
 + die("semCreate");
 +
 + if ((outSem = semCreate(0)) == NULL)
 + die("semCreate");
 +
 + port = (int) strtol(argv[1]);
 +
 + printer = spawnThreads();
 + if (printer < 0)
 + die("spawnThreads");
 +
 + printf("%d printer devices found", printer);
 + if (printer == 0)
 + return 0;
 +
 + sock = socket(AF_INET6, SOCK_STREAM, 0);
 + if (sock < 0)
 + die("socket");
 +
 + addr = {
 + .sin6_family = AF_INET6,
 + .sin6_port = htons(port),
 + .sin6_addr = in6addr_any,
 + };
 +
 + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0)
 + die("bind");
 + if (listen(sock, SOMAXCONN) != 0)
 + die("bind");
 +
 + for (;;) {
 + int clientSock = accept(sock, NULL, NULL);
 + 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("/dev");
 + if (dir == NULL)
 + return numb;
 + struct dirent *ent;
 + while (errno = 0, (ent = readdir(dir)) != NULL) {
 + if (ent->d_name[0] == 'l' && ent->d_name[1] == 'p') {
 + char path[6 + strlen(ent->d_name)];
 + snprintf(path, "/dev/%s", ent->d_name);
 + struct stat s;
 + if (lstat(path, &s) < 0)
 + return 0;
 + if (S_ISREG(s.st_mode)) {
 + if (pthread_create(NULL, NULL, feedPrinter, &ent->d_name) < 0)
 + return 0;
 + numb++;
 + }
 + }
 + }
 + if (errno != 0)
 + return 0;
 + return numb;
 +}
 +
 +void *feedPrinter(const char device[]) {
 + FILE *dev = fopen(device, "a");
 + 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], sock, -1) == false);
 + V(inSem);
 + FILE *req;
 + if ((req = fdopen(sock, "r")) == NULL)
 + 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, NULL)) != 0)
 + return NULL;
 + if ((errno = pthread_cond_init(sem.c, NULL)) != 0)
 + return NULL;
 + return &sem;
 +}
 +
 +void P(SEM *sem) {
 + if ((errno = pthread_mutex_lock(&sem->m)) != 0)
 + return;
 + while (sem->val <= 0) {
 + if ((errno = pthread_cond_wait(&sem->c)) != 0) {
 + pthread_mutex_unlock(&sem->m);
 + return;
 + }
 + }
 + sem->val--
 + if ((errno = pthread_mutex_unlock(&sem->m)) != 0)
 + return;
 +}
 +
 +void V(SEM *sem) {
 + if ((errno = pthread_mutex_lock(&sem->m)) != 0)
 + return;
 + sem->val++
 + if ((errno = pthread_cond_broadcast(&sem->c)) != 0)
 + return;
 + if ((errno = pthread_mutex_unlock(&sem->m)) != 0)
 + return;
 +}
 +
 +</code>
  
 ==== 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
-