===== März 2006 =====
==== Aufgabe 1 ====
* a) 2 (http://de.wikipedia.org/wiki/RAID_5#RAID_5:_Leistung_.2B_Parit.C3.A4t)
* b) 3
* c) 1 ist als falsch gedacht und unpassend formuliert (hat juk, glaube ich, gesagt; gemeint ist, daß alle Adressen zum Zeitpunkt des Programmstarts aufgelöst werden, aber das ist nicht richtig, weil es Adreßbezüge gibt, die vorher aufgelöst werden können.)
* d) 1
* e) 2
* f) 4
* g) 1
* h) 4
* i) 3
* j) 2
* k) 4
* l) 2
* m) 3
* n) 3
==== Aufgabe 2 ====
Zum testen müssen sem.c und sem.h selbst geschrieben werden.
* a)
/* author: Noya, Sven Pfaller */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
"sem.h"
pthread_mutex_t
//
for (int i
void *xxx(void *)
string.h
&
unlink
*/
/* Includes, Funktionsdeklarationen, globale Variablen */
#include
#include "sem.h"
#include
#define NBUFFER 9
#define PORT 7654
#define URL "localhost"
int main(int argc, char **argv);
static void process_jobs();
static void job(FILE *file);
static void *process_queue(void *data);
static void thread_error(char *msg);
static void error(char *msg);
static void num_error(char *msg, int num);
static FILE *buffer[NBUFFER];
static int bread;
static int bwrite;
static int sock;
static SEM *semfree;
static SEM *semfill;
static pthread_mutex_t block;
/* Funktion main */
int main(int argc, char **argv) {
/* lokale Variablen und was man sonst am Anfang so vorbereitet */
pthread_t thread;
struct sockaddr_in addr;
struct hostent *host;
int e;
int i;
bread = 0;
bwrite = 0;
/* Semaphore erzeugen und initialisieren */
semfree = sem_init(NBUFFER);
semfill = sem_init(0);
/* queue-Threads erzeugen */
for (i = 1; i < argc; i++) {
if ((e = pthread_create(&thread, NULL, process_queue, (void *) argv[i])) != 0) {
num_error("pthread_create", e);
}
}
/* Verbindung zu Printserver aufbauen */
host = gethostbyname(URL);
if (host == NULL) error("gethostbyname");
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1) error("socket");
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
if (connect(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1) error("connect");
/* Auftraege bearbeiten, Ende main */
process_jobs();
/* Ende von main - wird nie erreicht */
return 0;
}
/* Funktionen process_jobs */
static void process_jobs() {
FILE *cfile;
FILE *file;
char fname[PATH_MAX + 2];
while (1) {
P(semfill);
cfile = buffer[bread];
bread = (bread + 1) % NBUFFER;
V(semfree);
if (fgets(fname, PATH_MAX + 2, cfile) == NULL) error("fgets");
fname[strlen(fname) - 1] = '\0';
printf(".global: processing document (%s)...\n", fname);
file = fopen(fname, "r");
if (file == NULL) error("fopen");
job(file);
printf(".global: processing document (%s) done\n", fname);
fclose(cfile);
fclose(file);
/* if unlinking failes, ignore it */
unlink(fname);
}
}
/* Funktion job */
static void job(FILE *file) {
struct stat info;
int fd;
FILE *sockfp;
char buf[1024];
fd = fileno(file);
sockfp = fdopen(sock, "w");
if (sockfp == NULL) error("fdopen");
if (fstat(fd, &info) == -1) error("fstat");
if (fprintf(sockfp, "print job length=%i\n", info.st_size) < 0) error("fprintf");
while (fgets(buf, 1024, file) != NULL) {
if (fputs(buf, sockfp) == EOF) error("fputs");
}
if (feof(file) == 0) error("fgets");
fflush(sockfp);
}
/* Funktion process_queue */
static void *process_queue(void *data) {
char *dirname;
DIR *dir;
struct dirent *entry;
FILE *cfile;
char path[PATH_MAX + 1];
dirname = (char *) data;
while (1) {
dir = opendir(dirname);
if (dir == NULL) thread_error("opening directory failed");
errno = 0;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == 'c') {
snprintf(path, PATH_MAX + 1, "%s/%s", dirname, entry->d_name);
cfile = fopen(path, "r");
if (cfile != NULL) {
P(semfree);
pthread_mutex_lock(&block);
buffer[bwrite] = cfile;
bwrite = (bwrite + 1) % NBUFFER;
pthread_mutex_unlock(&block);
V(semfill);
printf("%s: found document control file (%s), added to global queue\n", dirname, entry->d_name);
/* if unlinking failes, ignore it */
unlink(path);
}
}
errno = 0;
}
if (errno != 0) thread_error("reading from directory failed");
closedir(dir);
}
}
static void thread_error(char *msg) {
perror(msg);
pthread_exit(NULL);
}
static void error(char *msg) {
perror(msg);
exit(1);
}
static void num_error(char *msg, int num) {
printf("%s: %s\n", msg, strerror(num));
exit(1);
}
* b)
# author: Noya, Sven Pfaller (kalterregen@gmx.net)
CFLAGS=-ansi -pedantic -D_POSIX_SOURCE -g
.PHONY: clean
lpqmanager: sem.o lpqmanager.o
gcc ${CFLAGS} -o lpqmanager lpqmanager.o sem.o -lpthread
sem.o: sem.c sem.h
gcc ${CFLAGS} -c -o sem.o sem.c
lpqmanager.o: lpqmanager.c
gcc ${CFLAGS} -c -o lpqmanager.o lpqmanager.c
clean:
rm -f *.o
rm -f lpqmanager
==== Aufgabe 3 ====
==== Aufgabe 4 ====
* a)
* b)
* c)
* d)