TP3 GestionCPU
TP3 GestionCPU
TP3 GestionCPU
ATTENTION : Comme il est très facile de faire des erreurs de programmations, vous
allez certainement créer des processus qui resteront en tâche de fond sans que vous le
sachiez. Lancez la commande top dans une fenêtre toujours visible pour vérifier si un
processus non désiré tourne encore.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
1/3
– envoie SIGSTOP à tous les fils.
– réveille un fils pendant 5 secondes (en se basant sur l’ordre de lancement des fils), en
utilisant les signaux SIGCONT et SIGSTOP.
2. Utiliser le programme scheduler écrit avec 3 fils faisant chacun les calculs suivants :
- 1er fils : boucle qui lit 100 entiers et affiche son factoriel.
- 2nd fils : boucle qui lit 100 chaînes de caractères et affiche si la chaîne est un palindrome.
-3ième fils : boucle imbriquée qui lit 100 entiers et pour chaque entier N, lit 100 autres
entiers M et affiche le résultat de la division du factoriel de N sur M.
Ajouter la vérification de la fin du processus pour l’enlever de la liste des processus fils prêts
à exécuter. Pour cela, utiliser la primitive suivante :
pid_t waitpid(pid_t pid, int *status, intoptions) avec l’option WNOHANG
void* thread1(void* n)
{
printf("Début Thread\n");
sleep(5);
printf("Thread : numéro : %d\n", pthread_self());
printf("Thread : Fin Thread\n");
pthread_exit(NULL);
}
int main()
{
pthread_t thr;
if (fork()==0)
{
// debut fils
printf("Début fils \n");
printf("Fils : pid=%d, ppid=%d\n", getpid(), getppid());
printf("Fils : numéro thread fils : %d\n", pthread_self());
printf("Fils : Fin Fils \n");
exit(0);
// Fin fils
}
// Suite du père
printf("Pere : pid=%d, ppid=%d\n", getpid(), getppid());
printf("Pere : Lancement Thread \n");
int r1=pthread_create(&thr,NULL,thread1,NULL);
sleep(2);
printf("Pere : numéro thread main : %d\n", pthread_self());
printf("Pere : Attente Fin thread %d \n", thr);
pthread_join(thr,NULL);
printf("Pere : Fin thread \n");
printf("Pere : Fin Pere \n");
return(0);
2/3
}
Compilez et exécutez.
Note : Pour compiler, il est nécessaire de préciser l’utilisation de la librairie qthreads. Pour
cela, utiliser la commande suivante :
gcc thread.c –o thread -lqthreads
Pour exécuter, il suffit de lancer ./thread
2°) Modifier ce programme de telle manière à créer deux threads dont le deuxième attend la
fin du premier (Montrer cela par des affichages).
Compléments d'information
Manipulation de threads
Les threads partagent le même espace d’adressage que leurs parents. Chaque thread peut
accéder aux varaibles globales du programme qui le crée. Cependant, comme les thrteads se
déroulent concuremment, on retrouve le problème d’accès concurent à une variable partagée
entre plusieurs threads.
Un thread est identifié par une variable de type pthread_t (entier long positif).
1. L’appel système pthread_create(……) crée un thread et démarre son execution :
Int pthread_create(
pthread_t* thread, // numéro identifiant le thread créé
pthread_attr_t* attr, // attributs ou NULL par défaut
void* (*fn) (void* arg), // fonction à exécuter (pointeur de fonction)
void* arg // arguments de la fonction
) ;
2. La fonction int pthread_exit (void* retour) termine le thread en cours d’exécution. Une
valeur de retour peut être récupérée par un autre thread par l’intermédiaire de la fonction :
int pthread_join(pthread_t thread, void** retour) ;
NULL en paramètre indique une absence de valeur de retour. Si le thread est détruit avant sa
fin normale par un autre thread, la valeur de retour est PTHREAD_CANCEL.
3. D’autres fonctions :
int pthread_detach(pthread_t thread) : récupérer ses ressources dès sa fin.
pthread_t pthread_self : fournit l’identifiant du thread courant.
int pthread_cancel(pthread_t thread) : détruit le thread.
Int pthread_join (pthread_t thread, void **retval): attend la fin d’un autre thread.
3/3