Du befindest dich hier: FSI Informatik » jahrgaenge » 2006 » "Muster"-Lösungen » "Muster"-Lösungen zu Klausuren aus Softwaresysteme 1 » Vordiplomsklausuren » März 2006
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung | |||
jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2006 [05.09.2007 11:55] – 131.188.30.106 | jahrgaenge:2006:loesungen:softwaresysteme_1:vordiplom:mar2006 [08.09.2007 16:34] (aktuell) – 88.65.116.180 | ||
---|---|---|---|
Zeile 19: | Zeile 19: | ||
==== Aufgabe 2 ==== | ==== Aufgabe 2 ==== | ||
+ | |||
+ | Zum testen müssen sem.c und sem.h selbst geschrieben werden. | ||
* a) | * a) | ||
<code c> | <code c> | ||
+ | /* author: Noya, Sven Pfaller */ | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | /* | ||
+ | " | ||
+ | pthread_mutex_t | ||
+ | // | ||
+ | for (int i | ||
+ | void *xxx(void *) | ||
+ | string.h | ||
+ | & | ||
+ | unlink | ||
+ | */ | ||
+ | |||
+ | /* Includes, Funktionsdeklarationen, | ||
+ | |||
+ | #include < | ||
+ | #include " | ||
+ | #include < | ||
+ | |||
+ | #define NBUFFER 9 | ||
+ | #define PORT 7654 | ||
+ | #define URL " | ||
+ | |||
+ | 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(& | ||
+ | num_error(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* Verbindung zu Printserver aufbauen */ | ||
+ | |||
+ | host = gethostbyname(URL); | ||
+ | if (host == NULL) error(" | ||
+ | |||
+ | sock = socket(PF_INET, | ||
+ | if (sock == -1) error(" | ||
+ | |||
+ | addr.sin_family = AF_INET; | ||
+ | addr.sin_port = htons(PORT); | ||
+ | memcpy(& | ||
+ | |||
+ | if (connect(sock, | ||
+ | |||
+ | /* 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, | ||
+ | |||
+ | fname[strlen(fname) - 1] = ' | ||
+ | |||
+ | printf(" | ||
+ | |||
+ | file = fopen(fname, | ||
+ | if (file == NULL) error(" | ||
+ | |||
+ | job(file); | ||
+ | |||
+ | printf(" | ||
+ | |||
+ | 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, | ||
+ | |||
+ | if (sockfp == NULL) error(" | ||
+ | |||
+ | if (fstat(fd, &info) == -1) error(" | ||
+ | |||
+ | if (fprintf(sockfp, | ||
+ | |||
+ | while (fgets(buf, 1024, file) != NULL) { | ||
+ | if (fputs(buf, sockfp) == EOF) error(" | ||
+ | } | ||
+ | if (feof(file) == 0) error(" | ||
+ | |||
+ | 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(" | ||
+ | |||
+ | errno = 0; | ||
+ | while ((entry = readdir(dir)) != NULL) { | ||
+ | if (entry-> | ||
+ | snprintf(path, | ||
+ | |||
+ | cfile = fopen(path, " | ||
+ | if (cfile != NULL) { | ||
+ | |||
+ | P(semfree); | ||
+ | |||
+ | pthread_mutex_lock(& | ||
+ | |||
+ | buffer[bwrite] = cfile; | ||
+ | bwrite = (bwrite + 1) % NBUFFER; | ||
+ | |||
+ | pthread_mutex_unlock(& | ||
+ | |||
+ | V(semfill); | ||
+ | |||
+ | printf(" | ||
+ | |||
+ | /* if unlinking failes, ignore it */ | ||
+ | unlink(path); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | errno = 0; | ||
+ | } | ||
+ | if (errno != 0) thread_error(" | ||
+ | |||
+ | 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(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
</ | </ | ||
* b) | * 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: | ||
+ | gcc ${CFLAGS} -c -o lpqmanager.o lpqmanager.c | ||
+ | |||
+ | clean: | ||
+ | rm -f *.o | ||
+ | rm -f lpqmanager | ||
+ | </ | ||
==== Aufgabe 3 ==== | ==== Aufgabe 3 ==== |