uni

University stuff
git clone git://git.christosmarg.xyz/uni-assignments.git
Log | Files | Refs | README | LICENSE

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 }