#include #include #include #include "sem.h" // Zum Kompilieren: `gcc -o sync 04-sync.c sem.o -pthread` // Da Semaphoren genutzt werden, muss auch die Objektdatei mit den // entsprechenden Funktionen (sem.o) angegeben werden. // "-pthread" ist noetig, da der Header pthread.h inkludiert wurde (u.a. fuer // pthread_create(3)). #define N 10000 static double a[N][N], sum; static SEM *semaphore; struct param { int index; }; static void initialize_array(void) { srand(0); for (size_t i = 0; i < N; i++) { for (size_t j = 0; j < N; j++) { a[i][j] = ((double)rand()) / RAND_MAX; } } } static void *sumRow(void *arg) { struct param *par = arg; double localSum = 0; for (size_t j = 0; j < N; j++) { localSum += a[par->index][j]; } // 2. Veraenderung: P() und V(), um den kritischen Abschnitt (Erhoehen der // "sum") zu schuetzen. Ohne diese Veraenderung wird man beim wiederholten // Ausfuehren feststellen, dass manchmal andere Summen ausgegeben werden // (was man gerne mal ausprobieren kann, indem man das P() und V() // auskommentiert). P(semaphore); sum += localSum; V(semaphore); return NULL; } int main(int argc, char *argv[]) { pthread_t tids[N]; struct param args[N]; initialize_array(); // 1. Veraenderung: Erzeugen der Semaphore. Hier mit dem initialen Wert 1, // da sie als Mutex ("gegenseitiger Ausschluss") dienen soll. semaphore = semCreate(1); if (semaphore == NULL) { perror("semCreate"); exit(EXIT_FAILURE); } for (int i = 0; i < N; i++) { args[i].index = i; pthread_create(&tids[i], NULL, sumRow, &args[i]); } for (int i = 0; i < N; i++) { pthread_join(tids[i], NULL); } printf("%lf\n", sum); // 3. Veraenderung: Freigeben der Semaphore. Siehe auch Dokumentation in sem.h. semDestroy(semaphore); }