Threads
Processus : tout est dupliqué (dont la mémoire), sauf :
- le système de fichiers
- la table des fichiers ouverts
- les allocations de mémoire partagée
Threads : tout ce qui est possible de partager est partagé (dont mémoire et descripteur de fichiers), sauf : - le contexte d’exécution (ex : la pile) qui contient l’endroit où on en est dans le code et les variables locales
Threads vs Processus
Processus | Threads |
---|---|
Peut se planter sans planter tout le programme (largement utilisé dans les navigateurs webs), (vrai uniquement pour les languages unsafe) | Moins chers (écart + grand sous Windows que sous Unix) |
Plus facile de partager les choses | Permissions identiques |
Permissions différentes | |
Threads système (ou processus léger) est visible au noyau et threads utilisateurs n’est utile que pour le développeur. |
- Modèle 1-1 \ra un thread utilisateur et un thread noyau : le + simple, mais pas le + efficace
- Module 1-N ou green threads \ra Tout dans l’espace utilisateur, + efficace, car on ne communique pas avec le noyau (aka pas d’appel système relou). Par contre :
- Problème avec les appels systèmes bloquant
- Utilises 1 seul CPU
- Modèle M-N \ra Il y a M threads utilisateurs multiplexés avec N threads noyaux avec M \gg N, utilisation d’un scheduler avec work-stealing (cf. Cilk) via une API utilisateur spécifique.
Implémentation
Java | Python | C |
---|---|---|
- <2 : 1-N - 2-16 : 1-1 - > 17 : M-N |
1-N | 3 bibliothèques : - pthreads (utile pour Posix) - Win32 threads (utile pour Windows) - threads C11 (compatible avec Posix et Windows) |
Pthreads
- Création d’un thread
int pthread_create(..., f, c);
// Avec
int f(void *c) -> f(c)
Souvent, on va envoyer une structure via c
, donc on la cast en void*
lors de la création du thread et on le recast vers notre structure à l’arrivée.
- Lier un thread
pthread_join
- Deux primitives de synchronisation
// Mutex
pthread_mutex_init
// Note : passer pthread_mutex_attribute à NULL
//
// Variable de condition
pthread_condvar_init