ex1_1.c (1938B)
1 #include <pthread.h> 2 #include <semaphore.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #define LEN(x) (sizeof(x) / sizeof(x[0])) 8 9 /* 10 * Εργαστήριο ΛΣ2 (Δ6) / Εργασία 2: Άσκηση 1.1 / 2020-2021 11 * Ονοματεπώνυμο: Χρήστος Μαργιώλης 12 * ΑΜ: 19390133 13 * Τρόπος μεταγλώττισης: `cc ex1_1.c -lpthread -o ex1_1` 14 */ 15 16 struct foo { 17 char *str; 18 sem_t mutex; 19 }; 20 21 /* Function declarations */ 22 static void *tdprint(void *); 23 static void *emalloc(size_t); 24 25 /* Global variables */ 26 static const char *nums[] = { /* Each thread will print one of these */ 27 "<one>", 28 "<two>", 29 "<three>", 30 }; 31 32 static void * 33 tdprint(void *foo) 34 { 35 struct foo *f; 36 37 f = (struct foo *)foo; 38 if (sem_wait(&f->mutex) < 0) 39 err(1, "sem_wait"); 40 printf("%s", f->str); 41 /* Prevent memory leak from strdup(2). */ 42 free(f->str); 43 if (sem_post(&f->mutex) < 0) 44 err(1, "sem_post"); 45 46 return NULL; 47 } 48 49 static void * 50 emalloc(size_t nb) 51 { 52 void *p; 53 54 if ((p = malloc(nb)) == NULL) 55 err(1, "malloc"); 56 57 return p; 58 } 59 60 int 61 main(int argc, char *argv[]) 62 { 63 struct foo *f; 64 pthread_t *tds; 65 int i, len, n = 5; 66 67 len = LEN(nums); 68 f = emalloc(sizeof(struct foo)); 69 /* 70 * Instead of hardcoding how many threads we want to have, the 71 * number of threads is always equal to how many elements the 72 * `nums` array has. That means in case we want to add/remove 73 * entries from `nums`, everything will adapt automatically. 74 */ 75 tds = emalloc(len * sizeof(pthread_t)); 76 77 if (sem_init(&f->mutex, 0, 1) < 0) 78 err(1, "sem_init"); 79 while (n--) { 80 for (i = 0; i < len; i++) { 81 if ((f->str = strdup(nums[i])) == NULL) 82 err(1, "strdup"); 83 if (pthread_create(&tds[i], NULL, tdprint, (void *)f) != 0) 84 err(1, "pthread_create"); 85 if (pthread_join(tds[i], NULL) != 0) 86 err(1, "pthread_join"); 87 } 88 } 89 printf("\n"); 90 91 (void)sem_destroy(&f->mutex); 92 pthread_exit(NULL); 93 free(tds); 94 free(f); 95 96 return 0; 97 }