/* Programm vom 13Jun22 (T03) */ #include #include #include #include /* Vergesse nicht sem.o und sem.h aus /proj/i4sp1/pub/aufgabe4 zu * holen! */ #include "sem.h" struct param { int index; /* Hier haben wir als "Parameter" für jeden Thread eine Referenz * für die geteilte Semaphore hinzugefügt, damit diese nicht als * globale Variable deklariert werden muss. */ SEM *sem; }; static double a[100][100], sum; static void *sum_row(void *arg) { struct param *par = arg; double localSum = 0; for(int j = 0; j < 100; j++) localSum += a[par->index][j]; /* Der "kritische Abschnitt" (von P(...) bis V(...)) besteht aus * der Inkrementierung von sum, da += nicht atomar ist (das * gleiche gilt auch für i++). Dieser sollte immer so kurz wie * möglich sein, damit das restliche Programm nicht überflüssig * verlangsamt wird. */ P(par->sem); sum += localSum; V(par->sem); return NULL; } int main() { pthread_t tids[100]; struct param args[100]; /* Die Semaphore muss erstellt werden, und hat Initial den Wert * 1, da nur ein Thread sich im kritischen Abschnitt befinden * darf. */ SEM *sem = semCreate(1); if (NULL == sem) { perror("semCreate"); return EXIT_FAILURE; } for(int i = 0; i < 100; i++) { args[i].index = i; /* Die Semaphore hat zunächst nur eine lokale Referenz, * damit diese aber sinnvoll benutzt werden müssen wir * sicherstellen das alle Fäden Zugriff auf diese haben, wie * bereits oben bei der definition von "struct param" * erwähnt. */ args[i].sem = sem; pthread_create(&tids[i], NULL, sum_row, &args[i]); } for(int i = 0; i < 100; i++) pthread_join(tids[i], NULL); /* Bevor sich das Programm beendet, müssen noch alle Ressourcen * freigegeben werden. Die Threads wurden bereits mit * pthread_join aufgesammelt und aufgeräumt, es fehlt noch die * Semaphore: */ semDestroy(sem); }