Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Prüfungen im Bachelor-Studium (1. - 5. Semester) » Lösungsvorschlag   (Übersicht)

Dies ist eine alte Version des Dokuments!


Lösungsvorschlag

Aufgabe 1.1: Einfachauswahl-Fragen

a) 2 b) 2 c) 1 d) 3 e) 2 f) 1 g) 3 h) 2 i) 4 j) 4

Aufgabe 2:

a)

/* 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;
}

Aufgabe 3:

a)

Kurzfristige Planung:
bereit nach laufend: dispatch
laufend nach bereit: relinquish
(schwebend) blockiert nach (schwebend) bereit: signal
laufend nach blockiert: wait 
Mittelfristige Planung:
nach/von schwebend: swap out/in

Langfristige Planung: (war eigentlich nicht gefragt)
laufend nach gestoppt: stop (an sich auch von bereit und blockiert aus möglich (SP2-091*  Folie  16))
gestoppt nach bereit: continue
erzeugt nach begreit: beginn
laufend nach beendet: end

Langfristig: (war eigentlich nicht gefragt)

  gestoppt, erzeugt, beendet

Mittelfristig:

  schwebend bereit, schwebend blockiert (aka ausgelagert)

Kurzfristig:

  blockiert, bereit, laufend
  

b)

Einplanung: (schwebend) blockiert nach bereit Umplanung: Prozess wird verdrängt oder gibt CPU freiwillig ab (relinquish) –> direkt von laufend nach bereit Anm: Einlasten (dispatching, nach laufend) ist nicht Einplanen (nach bereit)

c)

kooperativ
- Prozesse geben freiwillig ab [oder wird im Rahmen eines von ihm getätigten Systemaufrufs  verdrängt]
- Prozesse können CPU monopolisieren
- FCFS, zB sehr kurz laufende Prozesse
präemptiv 
- Prozesse werden verdrängt
- Typisch mehr Mehrbenutzer/Timesharing-Systemen
- RoundRobin, Feedback, Virtual Round Robin ist auch präemtiv

d)

nur laufend → bereit [relinquish] präemptiv: gewaltvoll kooperativ: freiwillig

Aufgabe 4:

a)

Durch die MMU, bei der Umrechnung der virtuellen Adress, durch das Present-Bit

b) (das muss man tatsaechlich so aufdroeseln um 8/8 zu bekommen)

1. MMU loest Trap (nicht Interrupt?) aus
2. BS loest Handler fuer Pagefault aus
3. freier Platz wird im Hauptspeicher gesucht ggf. andere Seite auslagern
4. Einlagerung von Platte angestossen
5. Prozess wird blockiert bist Einlagerung fertig ist
6. Interrupt (nicht Signal?) an Prozess um Mitzuteilen, dass Einlagerung abgeschlossen
7. Present-Bit wird auf 1 gesetzt
8. Prozess geht in Zustand bereit ueber
9. Befehl der den Trap ausgeloest hat wird wiederholt