Blame view

Threads/Mémo.txt 3.33 KB
0ae69087   pfrison   Ajout des fichiers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  Note : à la différence du fork, un thread ne créer pas de nouveau processus.
  
  #include <pthread.h>
  
  --- Compilation /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\
  Avec gcc il faut utiliser -l pthread
      gcc <programme> -l pthread
  
  --- Fonction hôte du thread
  C'est la fonction qui va être executer dans le thread, la forme est toujours :
      void *start_routine(void * args){
          // ...
      }
  
  --- Création du thread
  fonction :
      int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
      thread : id du thread (généré par la fonction)
      attr : attribu, (très, très) souvent NULL
      start_routine : fonction a executer dans le thread
      arg : les argument à passer à start_routine
  
  exemple :
      pthread tid; //thread id
      pthread_create(&tid, NULL, thread_fonction, NULL);
  
  --- Rejoindre un thread
  Suspend le thread qui appel la fonction et attend la terminaison du thread en argument.
  Un tread joinable (c'est le cas par défault) va attendre un pthread_join avant de libérer sa mémoire. Utiliser pthread_detach pour éviter ça.
  
  fonction :
      int pthread_join(pthread_t thread, void **status);
      thread : l'id du thread à attendre
      status : code de retour du thread attendu (généré par la fonction)
  
  exemple :
      pthread_join(tid, NULL);
  
  --- Détachement des threads
  Le mode détaché permet de libérer la mémoire après la terminaison. Sinon, il aurait fallu utiliser pthread_join pour le même résultat.
  
  fonction :
      int pthread_detach(pthread_t thread);
      thread : l'id du tread à détacher
  
  exemple:
      pthread_detach(tid);
  
  --- Terminaison des threads
  Termine le thread qui appel la fonction. Si le thread était le dernier actif, le processus se termine.
  
  fonction :
      void pthread_exit(void *status);
      status : code de terminaison
  
  exemple :
      pthread_exit(NULL);
  
  --- Les arguments des fonctions
  Les arguments sont tous en void*.
  
  Pour faire passer un int (exemple) :
      // -- coté création thread : int -> int* -> void*
      int arg = 5;
      // arg est int
      // &arg est int*
      // (void *) &arg est void*
      pthread_create([...], (void *) &arg);
  
      // coté thread : void* -> int* -> int
      void *arg;
      // arg est void*
      // (int *) arg est int*
      // *((int *) arg) ou *(int *) arg est int
      int n = *(int *) arg;
  
  Pour une chaine de char (exemple) :
      // -- coté création thread : char* -> void*
      char str[50];
      // str est char*
      // (void *) str est void *
      pthread_create([...], (void *) &str);
  
      // coté thread : void* -> char*
      void *arg;
      // arg est void*
      // (char *) arg est char*
      char *str = (char *) arg;
  
  Pour plusieur arguments, utiliser une structure (exemple) :
      struct deux_int {
          int a;
          int b;
      }
  
      // -- coté création thread : struct deux_int -> struct deux_int* -> void*
      int a = 1;
      int b = 3;
      struct deux_int ints;
      ints.a = a;
      ints.b = b;
      // ints est struct deux_int
      // &ints est struct deux_int*
      // (void *) &ints est void*
      pthread_create([...], (void *) &ints);
  
      // coté thread : void* -> struct deux_int* -> struct deux_int
      void *arg;
      // arg est void*
      // (struct deux_int *) arg est struct deux_int*
      // *(struct deux_int *) arg est struct deux_int
      struct deux_int ints = *(struct deux_int *) arg;
      int a = ints.a;
      int b = ints.b;