Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » September 2005   (Übersicht)

September 2005

Aufgabe 1

  • a) 1
  • b) 3
  • c) 2
  • d) 3 → Mit dem logischen Adreßraum alleine ist noch keine Virtualisierung erreicht. Diese muß noch mithilfe des logischen Adreßraums realisiert werden.
  • e) 3 (Korrekt, Quelle: #144)
  • f) 4
  • g) 3 (Skript C9-15… Ich les da aber nicht raus, ob 3 oder 4 korrekt ist) → 3 ist richtig. Der Prozeß wird in den kurzfristigen Zustand „blockiert“ überführt. Der Zustand „schwebend bereit“ gehört ja zur mittelfristigen Einplanung und wird dann vom Prozeß eingenommen, wenn dieser im Zustand „bereit“ wäre, aber sein gesamter Adreßraum (!) ausgelagert wurde. Dann könnte er aber auch nicht laufen bzw. auf einen Seitenfehler treffen.
  • h) 1
  • i) 3 → Da Traps synchron mit dem Programmablauf (bzw. der Ausführung eines Befehls) auftreten, entsteht dadurch kein „Wettrennen“ (Race-condition).
  • j) 3
  • k) 3
  • l) 3
  • m) 3 (Natürlich ist das möglich, man muß eben ggf. umorganisieren; also ist die 3 unwahr → richtig.)
  • n) 2

Aufgabe 2

  • a)

sem.c:

#include <stdlib.h>
#include <stdio.h>
#include "sem.h"
 
SEM *sem_init(int n) {
    SEM *s;
    s = (SEM *) malloc(sizeof(SEM));
    if (s == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    pthread_mutex_init(&s->m, NULL);
    pthread_cond_init(&s->c, NULL);
    s->s = n;
 
    return s;
}
 
void P(SEM *s) {
    pthread_mutex_lock(&s->m);
    while (s->s < 1) {
        pthread_cond_wait(&s->c, &s->m);
    }
    s->s--;
    pthread_mutex_unlock(&s->m);
}
 
void V(SEM *s) {
    pthread_mutex_lock(&s->m);
    s->s++;
    pthread_cond_broadcast(&s->c);
    pthread_mutex_unlock(&s->m);
}

fdserver.c:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pthread.h>
#include <string.h>
 
#include "sem.h"
 
#define NTHREAD 25
 
void *serve(void *arg);
void handle(FILE *socket, char path[]);
void fhandle(FILE *socket, char path[]);
void dhandle(FILE *socket, char path[]);
 
struct bufinfo {
    SEM *sem_full;
    SEM *sem_free;
    pthread_mutex_t lock;
 
    int socks[NTHREAD];
    int writep;
    int readp;
};
 
int main(int argc, char *argv[]) {
    struct bufinfo b;
    pthread_t tid[NTHREAD];
    int i;
    int sock;
    struct sockaddr_in saddr;
 
    b.writep = 0;
    b.readp = 0;
    b.sem_full = sem_init(0);
    b.sem_free = sem_init(NTHREAD);
    pthread_mutex_init(&b.lock, NULL);
 
    for (i = 0; i < NTHREAD; i++) {
        pthread_create(&tid[i], NULL, serve, &b);
    }
 
    sock = socket(PF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        return EXIT_FAILURE;
    }
 
    saddr.sin_family = AF_INET;
    saddr.sin_port = argc > 1 ? htons(atoi(argv[1])) : htons(31337);
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
    if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {
        perror("bind");
        return EXIT_FAILURE;
    }
    if (listen(sock, 20) == -1) {
        perror("listen");
        return EXIT_FAILURE;
    }
 
    while (1) {
        int clsock;
        struct sockaddr clsaddr;
        socklen_t clsaddr_len = sizeof(clsaddr);
 
        clsock = accept(sock, &clsaddr, &clsaddr_len);
        if (clsock == -1) {
            perror("accept");
            continue;
        }
 
        P(b.sem_free);
        b.socks[b.writep] = clsock;
        b.writep = (b.writep + 1) % NTHREAD;
        V(b.sem_full);
 
    }
 
    return 0;
}
 
void *serve(void *arg) {
    struct bufinfo *b = (struct bufinfo *) arg;
    int s;
    FILE *fd;
    char buffer[1024+2];
 
    P(b->sem_full);
    pthread_mutex_lock(&b->lock); 
    s = b->socks[b->readp];
    b->readp = (b->readp + 1) % NTHREAD;
    pthread_mutex_unlock(&b->lock);
    V(b->sem_free);
 
    fd = fdopen(s, "r+");
 
    while (fgets(buffer, 1024+2, fd) != NULL) {
        buffer[strlen(buffer)-1] = '\0';
        handle(fd, buffer);
    }
 
    return NULL;
}
 
void handle(FILE *socket, char path[]) {
    struct stat statinfo;
 
    if (stat(path, &statinfo) == -1) {
        fprintf(socket, "%s\n", strerror(errno));
        return;
    }
 
    if (S_ISDIR(statinfo.st_mode)) {
        dhandle(socket, path);
    } else if (S_ISREG(statinfo.st_mode)) {
        fhandle(socket, path);
    } else {
        fprintf(socket, "Error: Something special, but not a file or directory\n");
        return;
    }
}
 
void fhandle(FILE *socket, char path[]) {
    char buf[1024+2];
    FILE *fd;
 
    fd = fopen(path, "r");
    if (fd == NULL) {
        fprintf(socket, "%s\n", strerror(errno));
        return;
    }
 
    while (fgets(buf, 1024+2, fd) != NULL) {
        if (fputs(buf, socket) == EOF) {
            perror("errno");
            return;
        }
    } 
}
 
void dhandle(FILE *socket, char path[]) {
    DIR *dir;
    struct dirent entry;
    struct dirent *result;
    int err;
 
    dir = opendir(path);
    if (dir == NULL) {
       fprintf(socket, "Error: %s\n", strerror(errno));
    }
 
    while(((err = readdir_r(dir, &entry, &result)) == 0) && result != NULL) {
        fprintf(socket, "%s\n", entry.d_name);
    }
}
  • b)

Aufgabe 3

  • a)
  • b)
  • c)
    • c1)
    • c2)
    • c3)