Advertisement
1fractal

Untitled

Dec 9th, 2020
1,386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.60 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <pthread.h>
  7. #include <stdnoreturn.h>
  8.  
  9. #define DELAI_MAX 1000           // en ms
  10.  
  11. #define CHK(prim)   do { if ((prim) == -1) { raler (#prim); } } while (0)
  12. #define TCHK(exp)   do { if ((errno=(exp)) > 0) { raler (#exp); } } while (0)
  13.  
  14. struct arg {
  15.     int thrnum; //numero thread
  16.     pthread_barrier_t *pbarN; // pointer sur barrierre unique
  17.     pthread_mutex_t *pmtx; // mutex commun
  18.     pthread_cond_t cond; // lacondition est propre à chaque thread
  19.  
  20.     int vasy;
  21. };
  22.  
  23. noreturn void raler(const char *msg) {
  24.     perror(msg);
  25.     exit(1);
  26. }
  27.  
  28. void attente_aleatoire(unsigned int *seed, int max_en_ms) {
  29.     int delai_en_ms;
  30.  
  31.     delai_en_ms = max_en_ms * (rand_r(seed) / (double) RAND_MAX);
  32.     usleep(delai_en_ms * 1000);       // convertir en micro-secondes
  33. }
  34.  
  35. void *un_thread(void *arg) {
  36.     unsigned int seed;         // pour rand_r
  37.     int thrnum;                // mon numéro de thread
  38.     char nombre[100];         // numéro de thread converti en ASCII
  39.  
  40.  
  41.     (void) arg;                // pour -Wall -Wextra -Werror
  42.  
  43.     thrnum = 0;                // TODO remplacer 0 par numéro de thread
  44.  
  45.     // on initialise seed avec notre numéro de thread pour avoir des
  46.     // résultats reproductibles
  47.     seed = thrnum;
  48.     attente_aleatoire(&seed, DELAI_MAX);
  49.  
  50.     // TODO attendre l'ordre d'afficher le '+'
  51.     struct arg *a = arg;
  52.     thrnum = a->thrnum;
  53.     TCHK(pthread_barrier_wait(a->pbarN));
  54.     //todo: END
  55.  
  56.     CHK (write(1, "+", 1));
  57.  
  58.     // TODO attendre l'ordre d'afficher mon numéro
  59.     TCHK(pthread_barrier_wait(a->pbarN));
  60.  
  61.     TCHK(pthread_mutex_lock(a->pmtx));
  62.  
  63.     while (!a->vasy) {
  64.         TCHK(pthread_cond_wait(&a->cond, a->pmtx));
  65.     }
  66.     a->vasy = 0;
  67.     TCHK(pthread_mutex_unlock(a->pmtx));
  68.  
  69.     // TODO END attendre l'ordre d'afficher mon numéro
  70.  
  71.     (void) snprintf(nombre, sizeof nombre, "%d ", thrnum);
  72.     CHK (write(1, nombre, strlen(nombre)));
  73.  
  74.     return NULL;
  75. }
  76.  
  77.  
  78. int main(int argc, char *argv[]) {
  79.     int nthreads;
  80.     unsigned int seed = 0;             // pour rand_r
  81.  
  82.     if (argc != 2 || (nthreads = atoi(argv[1])) <= 0) {
  83.         fprintf(stderr, "usage: %s nb-threads\n", argv[0]);
  84.         fprintf(stderr, "\tavec nb-threads > 0\n");
  85.         exit(1);
  86.     }
  87.  
  88.     pthread_t tid[nthreads];
  89.  
  90.     /////
  91.     struct arg arg[nthreads];
  92.     pthread_barrier_t barN;
  93.     TCHK(pthread_barrier_init(&barN, NULL, nthreads + 1));
  94.     /////
  95.  
  96.     for (int i = 0; i < nthreads; i++) {
  97.         ////
  98.         arg[i].thrnum = i;
  99.         arg[i].pbarN = &barN;
  100.         arg[i].vasy = 0;
  101.  
  102.         /////
  103.         TCHK (pthread_create(&tid[i], NULL, un_thread, NULL));
  104.     }
  105.  
  106.     attente_aleatoire(&seed, DELAI_MAX);
  107.     CHK (write(1, "debut\n", 6));
  108.  
  109.     /////
  110.     TCHK(pthread_barrier_wait(&barN));
  111.     /////  ==> threads ecrivent '+'
  112.  
  113.  
  114.     TCHK(pthread_barrier_wait(&barN));
  115.  
  116.  
  117.     // TODO donner l'ordre aux threads d'écrire leur '+'
  118.  
  119.     CHK (write(1, "\n", 1));          // doit être affiché après tous les '+'
  120.  
  121.  
  122.     // TODO prévenir chaque thread à son tour d'afficher son numéro
  123.  
  124.  
  125.  
  126.  
  127.     for (int i = 0; i < nthreads; i++) {
  128.         /////
  129.         TCHK(pthread_mutex_lock(&mtx));
  130.         arg[i].vasy = 1;
  131.         TCHK(pthread_mutex_unlock(&mtx));
  132.  
  133.         // attendre la terminaison de chaque thread
  134.         TCHK (pthread_join(tid[i], NULL));
  135.         TCHK(pthread_cond_destroy(&arg[i].cond));
  136.  
  137.  
  138.     }
  139. //    TCHK(pthread_cond_destroy(&arg[i].cond));
  140.  
  141.  
  142.     CHK (write(1, "\n", 1));
  143.  
  144.     exit(0);
  145. }
  146.  
  147.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement