Vous êtes sur la page 1sur 23

Système d’exploitation 1

Rapport système d’exploitation : TP 2

Réalisé par :
GHANOUCH Issam
ES-SLASSI RAZZOUKI Mehdi
Système d’exploitation 2

1- Creation des threads:

#include <pthread.h>
#include <stdio.h>

void* print_xs (void* unused) {


while (1)
fputc ('x', stderr);
return NULL;
}

int main () {
pthread_t thread_id;

pthread_create (&thread_id, NULL, &print_xs, NULL);

while (1)
fputc ('o', stderr);
return 0;
}

En fait, dans la fonction main de ce programme, on fait la création d’un thread


par la déclaration d’une variable de type pthread_t, qui stockera l’identifiant du thread,
puis par un appel de la fonction pthread_create en lui passant dans les paramètres la
fonction de thread void* print_xs (void* args).
La fonction main contient une boucle infinie qui affiche les ‘o’ et le thread affiche
continuellement les ‘x’ sur l’écran.
Système d’exploitation 3

Voici une capture d’écran de l’exécution de ce code :

La succession des ‘x’ et des ‘o’ sur l’écran est imprévisible car le système
d’exploitation (Linux) passe la main alternativement aux deux threads.
Pour la fonction de thread print_xs, il se termine avec return NULL. Pour la
terminaison explicite du thread On peut la remplacer par l’appel de la fonction
pthread_exit(NULL).

2- Transmettre des données à un thread :

#include <pthread.h>
#include <stdio.h>

Struct char_print_parms {
/* Caractère à afficher. */
Char character ;
/* Nombre de fois où il doit être affiché. */
Int count ;
};

/* Affiche un certain nombre de caractères sur stderr.*/


Système d’exploitation 4

void* char_print (void* parameters) {


struct char_print_parms* p = (struct char_print_parms*) parameters;
int i;
for (i = 0; i < p->count; ++i)
fputc (p->character, stderr);
return NULL;
}

int main () {
pthread_t thread1_id;
pthread_t thread2_id;

struct char_print_parms thread1_args;


struct char_print_parms thread2_args;

/* Crée un nouveau thread affichant 30 000 x. */

thread1_args.character = 'x';
thread1_args.count = 30000;
pthread_create (&thread1_id, NULL, &char_print, &thread1_args);

/* Crée un nouveau thread affichant 20 000 'o'. */

thread2_args.character = ‘o’;
thread2_args.count = 20000;
pthread_create (&thread2_id, NULL, &char_print, &thread2_args);

Return 0 ;
}

Dans ce programme, nous avons créé 2 threads (thread1_id et thread2_id), l’un


affiche sur l’écran des ‘x’ et l’autre des ‘o’, un certain nombre de fois, et ce par la même
fonction de thread print_char, mais à laquelle on a passé des valeurs différentes pour
chaque thread.
Mais l’exécution de ce code n’a rien affiché sur l’écran car les valeurs passées
en paramètres pour les 2 threads sont des variables locales créées par la fonction
main.
Le problème avec ce code c’est que rien n’empêche Linux d’ordonnancer les
threads de telle sorte que main termine en premier ce qui provoque la destruction de
ces variables locales.
Pour remédier à cette situation, nous avons utilisé la fonction pthread_join pour
forcer main à attendre la fin de l’exécution des deux threads.
Système d’exploitation 5

Voici le morceau de code qu’on a ajouté à la fin de la fonction main.

pthread_join (thread1_id, NULL); //S'assure que le 1er thread est terminé


pthread_join (thread2_id, NULL); // S'assure que le 2° thread est terminé

Maintenant, ce code est bel et bien exécuté.

3- Synchronisation et Sections Critiques :

La programmation des threads demande beaucoup de rigueur, car même qu’ils


donnent plus d’avantages et plus d’optimisation, ils ont beaucoup de risque tel qu’ils
partagent le même espace adressable.
Puisque le System d’exploitation est un system préemptif, il peut basculer entre
plusieurs threads facilement ce qui peut produire que nous ne pouvons pas toujours
reproduire facilement le comportement ayant causé le problème
La cause la plus vicieuse de plantage des programmes utilisant les threads est
lorsque ceux-ci tentent d'accéder aux mêmes données. Ces bogues sont appelés
conditions de concurrence critique ; parce qu’ils sont en concurrence pour modifier la
même section critique.

3-1. Conditions de Concurrence Critique :

Soit un programme ait une série de tâches en attente traitées par plusieurs
threads concurrents.
Fonction de Thread Traitant une File de Tâches job-queue1.c :

#include <malloc.h>
#include<pthread.h>
struct job {
struct job* next;
int jobe;
};
Système d’exploitation 6

struct job* job_queue=NULL;


void process_job (struct job* job_i)
{
Printf ("Mon job porte numero %d \n", job_i->jobe) ;
}
void* thread_function (void* arg)
{
while (job_queue! = NULL) {
struct job* next_job = job_queue;
job_queue = job_queue->next;
process_job (next_job);
/* Libération des ressources. */
free (next_job);
}
return NULL;}
void Afficher (struct job* job_queue)
{
struct job* p = job_queue;
if(p==NULL) printf ("LISTE VIDE \n");
else
{
While (p != NULL ){
Printf (" NUMERO %d \n", p->jobe);
p = p->next;
}}}
void Remplir_Struct ()
{
int i =0, j = 0 ;
while(j<=6)
{
Système d’exploitation 7

struct job* nv_job = (struct job*) malloc (sizeof(struct job));


nv_job->jobe = ++i;
nv_job->next=job_queue;
job_queue = nv_job;
j++;}}
int main ()
{
pthread_t thread1, thread2;
Remplir_Struct () ;
Printf (" \t\t___________________________________ \n") ;
Printf (" \t\tDURANT L’APPEL AU THREAD : \n ") ;
pthread_create (&thread1, NULL, &thread_function, NULL);
pthread_create thread2, NULL, &thread_function, NULL);
pthread_join (thread1, NULL);
pthread_join (thread2, NULL); printf (" \t\t___________________________________
\n");
Printf (" \t\t LA LISTE A LA FIN : \n" );
Afficher (job_queue) ;
Return 0 ;
}

Supposons que votre programme ait une série de tâches en attente


traitées par plusieurs threads concurrents. La file d'attente des tâches est
représentée par une liste chaînée d'objets struct job.
Après que chaque thread a fini une opération, il vérifie la file pour voir si une
nouvelle tâche est disponible. Si job_queue n'est pas NULL, le thread supprime
la tête de la liste chaînée et fait pointer job_queue vers la prochaine tâche de la
liste.
Système d’exploitation 8

Voici l’exécution Normal du programme :

 Dans ce programme, problème n’est rencontré, mais néanmoins,


l’apparition de l’un de ces problèmes peut se produire, A savoir :

Supposant maintenant que 2 threads finissent leurs jobs en même temps


, et il ne reste qu’un seul élément dans la liste chainée , ainsi le 1ére thread
vérifie et trouve qu’il reste encore une tache à faire , il va pointer sur cet élément
, mais Linux interrompe ce thread et donne la main au 2éme thread , aussi ce
dernier vérifie et trouve qu’il reste encore un élément à faire ; ainsi on a 2
threads qui exécute le même tache .

Pire, un des 2 threads finis l’exécution de son job, il fait la libération de


l’élément dans la liste, Lorsque l'autre évaluera job_queue->next, il en résultera
une erreur de segmentation.

 Il faut penser de toute sorte que les opérations soit atomique et non
interrompu.
Donnant l’exemple de notre programme : Il faut vérifier la valeur de
job_queue et si elle n'est pas NULL, supprimer la première tâche, tout cela
en une seule opération atomique.
Système d’exploitation 9

Voici l’exécution avec erreur du programme :

3-2- MUTEXES :

Les MUTEX (Exclusion Mutuelle) est une solution pour rendre des opérations
atomiques,
Pour protéger les concurrences d’accès aux ressources critiques. Donc le
MUTEX est un verrouillage spécial, si un thread a verrouillé un MUTEX et un
2éme vient pour verrouiller le même MUTEX, il reste bloqué ou suspendu
jusqu‘à ce que l’autre thread quitte la section critique.

La Déclaration des MUTEX : Pthread_mutex_t mutex ;


L’initialisation de Mutex sans attribut : pthread_mutex_init (&mutex, NULL);

Une Initialisation simple est :


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

- Un thread peut verrouiller un mutex par : pthread_mutex_lock(&mutex) ;


- Le déverrouillage se fait par : pthread_mutex_unlock(&mutex) ;

Quand le thread exécute pthread_mutex_unlock : il déverrouillé le mutex, ainsi


un thread choisis aléatoirement entre dans la section critique s’il y avait un en
attente, sinon la mutex reste déverrouillé.
Système d’exploitation 10

Fonction de Thread Traitant une File de Tâches en utilisant les MUTEX job-queue1.c:

En ajoutant la fonction de thread suivante qui respecte l’exclusion mutuelle :

pthread_mutex_t job_queue_mutex = PTHREAD_MUTEX_INITIALIZER;

void* thread_function ()

while (job_queue! = NULL) {

pthread_mutex_lock (&job_queue_mutex);

struct job* next_job = job_queue;

job_queue = job_queue->next;

pthread_mutex_unlock (&job_queue_mutex);

/* Traite la tâche. */

process_job (next_job);

/* Libération des ressources. */

free (next_job);

pthread_exit(NULL);

Avec le mécanisme du MUTEX, nous avons fait en sorte à ce que les problèmes
de segmentation ne surviennent plus !

3-3- Inter blocage de Mutexes :

Un inter blocage survient lorsqu’un ou plusieurs threads sont bloqués en attendant


quelque chose qui n'aura jamais lieu.
Les mutex peuvent aussi poser ce problème à savoir :
1- Le verrouillage d'un mutex provoquera un inter blocage. Une tentative de
verrouillage sur le mutex est bloquante jusqu'à ce que le mutex soit déverrouillé.
Mais comme le thread est bloqué sur un mutex qu'il a lui-même verrouillé, le
verrou ne pourra jamais être supprimé.
Système d’exploitation 11

2- Lorsque 2 threads utilisent 2 mutex mais chaqu’un d’eux utilisent un ordre


différent de l’autre :

Thread 1 thread 2

‘A’ Pthread_mutex_lock(&mutex1) ‘C’ Pthread_mutex_lock(&mutex2)

‘B’ Pthread_mutex_lock(&mutex2) ‘D’ Pthread_mutex_lock(&mutex1)

Section Critique Section Critique

Pthread_mutex_unlock(&mutex2) Pthread_mutex_unlock(&mutex1)

Pthread_mutex_unlock(&mutex1) Pthread_mutex_unlock(&mutex2)

Supposant le thread 1 exécute A qui entraine le verrouillage du mutex 1, après


Linux donne la main au thread 2 qui exécute C qui entraine le verrouillage du
mutex 2
 Les 2 mutex sont verrouillés : Inter blocage des 2 threads.

3- Le verrouillage d'un mutex récursif ne cause pas d'inter blocage. Un mutex


récursif peut être verrouillé plusieurs fois par le même thread. Ce thread doit
effectuer autant d'appels à pthread_mutex_unlock que ceux de
pthread_mutex_lock pour que le mutex soit effectivement déverrouillé et qu'un
autre thread puisse y accéder.

Les mutex ont des attributs qu’on peut manipuler, l’appel de


pthread_mutex_INITIALIZER créer des attributs par défauts, mais néanmoins
on peut ajouter d’autre attributs à savoir :
- Declarer l’attribut: pthread_mutexattr_t attr;
- Déclarer le Mutex : pthread_mutex_t mutex ;
- Initialiser l’attribut: pthread_mutexattr_init (&attr);
- Définir le type de Mutex :
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
- Créer un mutex de type désiré : pthread_mutex_init (&mutex, &attr);
- Détruire l’objet d’attribut : pthread_mutexattr_destroy (&attr);
Système d’exploitation 12

Exemple du programme<< après avoir initialisé le mutex de type désire : >>

void* thread_function (void* arg)


{
int n = * ((int *) arg);
while (job_queue!= NULL) {
/* Récupère la tâche suivante. */
pthread_mutex_lock (&job_queue_mutex);
pthread_mutex_lock (&job_queue_mutex);
pthread_mutex_lock (&job_queue_mutex);
struct job* next_job = job_queue;
/* Supprime cette tâche de la liste. */
job_queue = job_queue->next;
pthread_mutex_unlock (&job_queue_mutex);
pthread_mutex_unlock (&job_queue_mutex);
pthread_mutex_unlock (&job_queue_mutex);
/* Traite la tâche. */
process_job (next_job);
/* Libération des ressources. */
free (next_job);
}
pthread_exit(NULL);
5-4.
} Vérification de Mutex non Bloquante :

La fonction pthread_mutex_lock a l’inconvénient d’être bloquante pour le


thread appelant dans le cas où le mutex est déjà verrouillé. Pour permettre au
thread d’effectuer d’autres taches au lieu de rester bloquer, on peut utiliser la
primitive pthread_mutex_trylock.
Système d’exploitation 13

3-4- Sémaphores pour les Threads :

Les mutex est une méthode puissante qui permet de protéger un morceau de
code accédant à une ressource critique, mais ne sont pas très efficaces dans certains
cas.
Par exemple on suppose que les 2 threads, chargés du traitement des tâches
stockées dans la liste chainée, terminent l’exécution de toutes les tâches. Dans ce cas,
ils se terminent systématiquement et si d’autres tâches arrivent elles ne seront pas
traitées.
Donc on va utiliser les sémaphores qui permettent d’endormir les threads
jusqu’à l’arrivée de nouvelles tâches.
Pour les utiliser on a besoin de définir un sémaphore sem_t job_queue_count
et de l’initialiser avec sem_init (&job_queue_count, 0, 0).
Au début de la fonction du thread nous avons appelé la fonction sem_wait et
après avoir ajouté une tâche dans la file on appele la fonction sem_post.

#include <malloc.h>
#include<pthread.h>
#include <semaphore.h>

sem_t job_queue_count;
pthread_mutex_t job_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
struct job {
/* Champ de chaînage. */
struct job* next;
/* Autres champs décrivant la tâche... */
int jobe ;
};
/* Liste chaînée de tâches en attente. */
struct job* job_queue = NULL;
Système d’exploitation 14

/* Traite les tâches jusqu'à ce que la file soit vide. */

void process_job(struct job* job_i)


{
printf("Je suis un thread , Mon job porte numero %d \n",job_i->jobe) ;

}
void* thread_function (void* arg)
{

while (1) {
/* Récupère la tâche suivante. */
sem_wait (&job_queue_count);
pthread_mutex_lock (&job_queue_mutex);
struct job* next_job = job_queue;
/* Supprime cette tâche de la liste. */
//n=0 ? sleep(0) : sleep(1) ;
job_queue = job_queue->next;
process_job (next_job);
pthread_mutex_unlock (&job_queue_mutex);
/* Traite la tâche. */

/* Libération des ressources. */

free (next_job);

}
pthread_exit(NULL);
Système d’exploitation 15

void Afficher(struct job* job_queue )


{
struct job* p = job_queue ;
if(p==NULL) printf("LISTE VIDE \n");
else
{
while(p != NULL )
{
printf(" NUMERO %d \n",p->jobe);
p = p->next;
}
}
}

void Remplir_Struct(int a)
{

struct job* nv_job = (struct job*) malloc(sizeof(struct job));


nv_job->jobe = a ;
pthread_mutex_lock (&job_queue_mutex);
nv_job->next=job_queue ;
job_queue = nv_job ;
sem_post (&job_queue_count);
pthread_mutex_unlock (&job_queue_mutex);

int main()
Système d’exploitation 16

{
int i;
pthread_t thread1 , thread2 ;
sem_init (&job_queue_count, 0, 0);

for(i=0 ; i<10 ; i++)


Remplir_Struct(i);

pthread_create(&thread1 , NULL , &thread_function ,NULL) ;


pthread_create(&thread2 , NULL , &thread_function , NULL) ;

sleep(2);

for(i=11 ; i<20 ; i++)


Remplir_Struct(i);

sleep(2);

for(i=30 ; i<39 ; i++)


Remplir_Struct(i);

pthread_join(thread1 ,NULL) ;
pthread_join(thread2 , NULL ) ;

return 0 ;

}
Système d’exploitation 17

Voici une capture d’écran de l’exécution de ce code.

Ainsi, nous avons réussi à mettre en œuvre un mécanisme pour que les threads
chargés du traitement des taches ne se terminent jamais. Si aucune tâche n'est
disponible pendant un certain temps, les threads sont simplement bloqués dans
sem_wait (&job_queue_count).

Après avoir ajouté une tâche à la file, elle envoie un signal de réveil au
sémaphore, indiquant qu'une nouvelle tâche est disponible par sem_post
(&job_queue_count).

3-5- Variable de conditions :

Jusqu’à maintenant on a vu 2 solutions pour gérer la synchronisation des threads :


-Mutex (Exclusion mutuelle)
-Sémaphore
Maintenant on va voir une troisième solution pour gérer la synchronisation :
Variable de Conditions.
Système d’exploitation 18

Variable de condition :
Une variable de condition vous permet de spécifier une condition qui lorsqu'elle
est remplie autorise l'exécution du thread et inversement, une condition qui lorsqu'elle
est remplie bloque le thread. Du moment que tous les threads susceptibles de modifier
la condition utilisent la variable de condition correctement, Linux garantit que les
threads bloqués à cause de la condition seront débloqués lorsque la condition change.
Fonctions pour manipuler les variables de conditions :
-pthread_cond_init : initialise une variable de condition. Le premier argument
est un pointeur vers une variable pthead_cond_t. Le second argument, un
pointeur vers un objet d'attributs de variable de condition, est ignoré par
GNU/Linux. Le mutex doit être initialisé à part, comme indiqué dans la Section
4.4.2, « MUTEXES ».
-pthread_cond_signal : valide une variable de condition. Un seul des threads
bloqués sur la variable de condition est débloqué. Si aucun thread n'est bloqué
sur la variable de condition, le signal est ignoré. L'argument est un pointeur vers
la variable pthread_cond_t. Un appel similaire, pthread_cond_broadcast,
débloque tous les threads bloqués sur une variable de condition, au lieu d'un
seul.
-pthread_cond_wait : bloque l'appelant jusqu'à ce que la variable de condition
soit validée.
L'argument est un pointeur vers la variable pthread_cond_t. Le second
argument est un pointeur vers la variable pthread_mutex_t. Lorsque
pthread_cond_wait est appelée, le mutex doit déjà être verrouillé par le thread
appelant. Cette fonction déverrouille automatiquement le mutex et se met en attente
sur la variable de condition. Lorsque la variable de condition est validée et que le
thread appelant est débloqué, pthread_cond_wait réacquiert automatiquement un
verrou sur le mutex.
Implémentation Simple de Variable de Condition spin-condvar.c

#include <pthread.h>
int thread_flag;
pthread_mutex_t thread_flag_mutex;
void initialize_flag ()
{
pthread_mutex_init (&thread_flag_mutex, NULL);
thread_flag = 0;
}
/* Appelle do_work de façon répétée tant que l'indicateur est actif ; sinon,
tourne dans la boucle. */
void* thread_function (void* thread_arg)
{
Système d’exploitation 19

while (1) {
int flag_is_set;
/* Protège l'indicateur avec un mutex. */
pthread_mutex_lock (&thread_flag_mutex);
flag_is_set = thread_flag;
pthread_mutex_unlock (&thread_flag_mutex);
if (flag_is_set)
do_work ();
/* Rien à faire sinon, à part boucler. */
}
Return NULL ;
}
/* Positionne la valeur de l'indicateur de thread à FLAG_VALUE. */
Void set_thread_flag (int flag_value)
{
/* Protège l'indicateur avec un verrouillage de mutex. */
pthread_mutex_lock (&thread_flag_mutex);
thread_flag = flag_value;
pthread_mutex_unlock (&thread_flag_mutex);
}

Dans cet exemple, on une fonction de thread qui exécute une boucle infinie,
accomplissant une tâche à chaque itération. La boucle du thread, cependant, a besoin
d'être contrôlée par un indicateur : la boucle ne s'exécute que lorsqu'il est actif ; dans
le cas contraire, la boucle est mise en pause.

Contrôler un Thread avec une Variable de Condition condvar.c

#include <pthread.h>
int thread_flag;
pthread_mutex_t thread_flag_mutex;
void initialize_flag ()
{
pthread_mutex_init (&thread_flag_mutex, NULL);
thread_flag = 0;
}
/* Appelle do_work de façon répétée tant que l'indicateur est actif ; sinon,
tourne dans la boucle. */
void* thread_function (void* thread_arg)
{
while (1) {
int flag_is_set;
/* Protège l'indicateur avec un mutex. */
Système d’exploitation 20

pthread_mutex_lock (&thread_flag_mutex);
flag_is_set = thread_flag;
pthread_mutex_unlock (&thread_flag_mutex);
if (flag_is_set)
do_work ();
/* Rien à faire sinon, à part boucler. */
}
Return NULL;
}
/* Positionne la valeur de l'indicateur de thread à FLAG_VALUE. */
Void set_thread_flag (int flag_value)
{
/* Protège l'indicateur avec un verrouillage de mutex. */
pthread_mutex_lock (&thread_flag_mutex);
thread_flag = flag_value;
pthread_mutex_unlock (&thread_flag_mutex);
}

Dans ce deuxième programme on a essayé d’optimiser le premier programme,


en utilisant une variable de condition pour protéger l'indicateur. Notez qu'au sein de
thread_function, un verrou est posé sur le mutex avant de vérifier la valeur de
thread_flag. Ce verrou est automatiquement libéré par pthread_cond_wait avant qu'il
ne se bloque et automatiquement réacquis ensuite.
Résumé :
Une variable de condition doit être accompagnée d'un mutex, qui nous
permet d’implémenter des conditions d'exécution plus complexes pour le
thread.

3-6- Interbloacage avec deux threads ou plus :

Lors de l’utilisation du mécanisme des variables conditions il faut faire attention


aux problèmes d’inter blocage des threads qui peuvent survenir.
2 situations peuvent se présenter :
-Soit que chacun des threads est bloqué en attendant une condition que l’autre
thread va valider donc dans ce cas les 2 threads restent bloqués
-Soit dans le cas où les threads verrouillent les mutex des ressources critiques
dans le même ordre.
Système d’exploitation 21

4- Implémentation des Threads sous GNU/Linux :

L'implémentation des threads POSIX sous GNU/Linux diffère de


l'implémentation des
Threads sous beaucoup de systèmes de type UNIX sur un point important : sous
GNU/Linux, les threads sont implémentés comme des processus. Lorsque vous
appelez pthread_create pour créer un nouveau thread, Linux crée un nouveau
processus qui exécute ce thread.
Cependant, ce processus n'est pas identique à ceux créés au moyen de fork ; en
particulier, il partage son espace d'adressage et ses ressources avec le processus
original au lieu d'en recevoir des copies.

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* thread_function (void* arg)
{
fprintf (stderr, "L'identifiant du thread fils est %d\n", (int) getpid ());
/* Boucle indéfiniment. */
while (1);
return NULL;
}
int main ()
{
pthread_t thread;
fprintf (stderr, "L'identifiant du thread principal est %d\n",(int)getpid());
pthread_create (&thread, NULL, &thread_function, NULL);
/* Boucle indéfiniment. */
while (1);
return 0;
}

Explication :
Le programme thread-pid du Listing threadpid le démontre. Le programme crée un
thread ; le thread original et le nouveau appellent tous deux la fonction getpid et
affichent leurs identifiants de processus respectifs, puis bouclent indéfiniment.
Système d’exploitation 22

Exécution :

4-1- Gestion de Signaux :

Gestion des signaux est basée sur le fait que chaque thread a le même
comportement d’un signal c’est à dire identifier par un pid, et comme chaque signal
ne concerne qu’un seul processus (en passant en paramètre le pid). ceci offre un
mécanisme d’échange entre les threads ( et les processus en général )

4-2- L'appel Système clone :

Threads GNU/Linux : créés dans le même programme soient implémentés comme


des processus séparés, ils partagent leur espace mémoire virtuel et leurs autres
ressources.
Fork : Un processus fils créé avec fork, cependant, copie ces objets.
L'appel système clone de Linux : est une forme hybride entre fork et
pthread_create qui permet à l'appelant de spécifier les ressources partagées entre lui
Système d’exploitation 23

et le nouveau processus. Clone nécessite également que vous spécifiiez la région


mémoire utilisée pour la pile d'exécution du nouveau processus.

5- Comparaison Processus/Threads :

Dans ce tableau on présente les différences entre les processus et les threads

Thread Processus
-Les threads d'un programme doivent -Un processus fils, au contraire, peut
exécuter le même code exécuter un programme différent en
-Un thread peut endommager les utilisant une fonction exec.
données d'autres threads du même -Chaque processus dispose de sa
processus car les threads partagent le propre copie de l'espace mémoire du
même espace mémoire et leurs programme.
ressources. -Les processus devraient être utilisés
-Les programmes qui ont besoin d'un pour des programmes ayant besoin
parallélisme finement contrôlé d'un parallélisme plus grossier.
-Le partage de données entre des -Le partage de données entre des
threads est trivial car ceux-ci partagent processus nécessite l'utilisation de
le même espace mémoire. mécanismes IPC