TP F2R101D Process
Ce TP a pour objectif de manipuler les différentes implémentations de processus sous Linux et Contiki.
Processus et Thread sous Linux
Dans cette partie du TP, vous allez étudier les différences et similitudes entre les processus et les threads sous Linux.
Processus
Vous allez écrire un programme qui va créer, au moment de son lancement un second processus. Vous allez faire appel à la fonction fork qui permet la création de ce processus.
Le retour de la fonction fork permet de déterminer dans quel processus le code est exécuté par la suite (voir la page man de la fonction fork)
pid_t pid; pid = fork(); if (pid == 0) { // Code du processus fils } else if (pid > 0) { // Code du processus parent } else { // Gestion d'erreur de fork }
![]() |
Pour quelles raisons l'appel à la fonction fork peut échouer ?
|
Votre programme contiendra 2 variables : une variable globale initialisée en dehors de la fonction main et une variable locale à la fonction main. Ces deux variables seront modifiées par le processus parent et le processus fils avant d'être affichées.
Chaque processus sera ensuite appel à la fonction sleep pendant 20s afin de pouvoir observer le retour de la commande ps u.
![]() |
Ne pas oublier d'inclure le fichier time.h pour la fonction sleep |
#include <time.h>
Ecrivez le programme fork.c selon les consignes précédentes et compilez le.
Exécutez le programme et observez les variables affichées.
![]() |
Quelle est la portée des modifications des variables faites par chaque processus ? Expliquez pourquoi.
|
![]() |
Observez le résultat de la commande ps u pendant l'exécution du programme. Que remarquez vous ?
|
Threads
Linux implémente les threads suivant la spécification POSIX Thread. Vous allez écrire un programme basés sur cette interface, mettant en oeuvre 2 threads. Comme pour le programme précédent, chaque thread modifiera 2 variables globales et locales avant de les afficher, afin de vérifier la portée de ces modifications.
- La création d'une thread passe par la fonction pthread_create à laquelle est passé en argument la fonction qui sera exécutée dans la thread.
- La fonction main fera appel à la fonction pthread_join afin d'attendre la fin de l'exécution des 2 threads.
#include <pthread.h> void *print_vars() { ... } int main(void) { pthread_t thread; pthread_create(&thread, NULL, &print_vars, NULL); pthread_join(thread, NULL); }
Pour compiler votre programme, vous aurez besoin d'ajouter l'option -pthread au compilateur.
Ecrivez le programme selon les consignes données et compilez le.
Exécutez le programme et observez les variables affichées.
![]() |
Quelle est la portée des modifications des variables faites par chaque processus ? Expliquez pourquoi.
|
![]() |
Observez le résultat de la commande ps u pendant l'exécution du programme. Que remarquez vous ?
|
Exécution concurrente sous Contiki
Contiki prévoit la possibilité de définir plusieurs processus dans un même firmware. L'ordonnancement peut se faire alors soit par des événements du kernel, comme les timers, soit par des messages passés entre processus.
Processus ordonnancés par timers
Vous allez écrire une programme Contiki contenant 2 processus : un rédacteur et un lecteur.
Le premier processus rédacteur va incrémenter une variable globale régulièrement (toutes les 4s). Le processus lecteur va, dans un premier temps, consulter cette variable plus fréquemment (toutes les secondes), vérifier si elle a été modifiée et afficher le cas échéant la nouvelle valeur.
Le programme aura donc la structure suivante :
static int var_glb = 0; // Déclaration des processus ... // Démarrage des processus ... PROCESS_THREAD(writer, ev, data) { // Code du rédacteur } PROCESS_THREAD(reader, ev, data) { // Code du lecteur }
Ecrivez le programme selon les consignes données et compilez le
![]() |
Vous aurez besoin d'une variable locale pour le lecteur, afin de sauvegarder la dernière valeur lue. |
![]() |
Quelle propriété faut-il ajoutée à cette variable ? Pourquoi ?
|
Exécutez le programme dans le simulateur et observez le comportement
![]() |
Combien de temps s'écoule entre le moment où la variable est modifiée et celui où le lecteur notifie le changement ? Ce temps peut-il être toujours le même ?
|
![]() |
Comment diminuer simplement ce décalage ?
|
![]() |
En quoi cette solution n'est pas optimal ?
|
Processus ordonnancés par messages
Vous allez maintenant modifier le processus lecteur pour se réveiller non pas sur un timer, mais sur un événement généré par le rédacteur à la mise à jour de la variable.
L'événement sera envoyé par le rédacteur grâce à la fonction suivante :
process_post(&reader, PROCESS_EVENT_CONTINUE, NULL);
Le lecteur se réveillera sur cette événement grâce à la fonction :
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);
Notez que la variable ev est celle définie dans la macro PROCESS_THREAD. C'est elle qui contient les événements à destination du processus. La variable data contient elle des données propres à l'événement. Dans le cas présent, les données sont NULL, comme le dernier paramètre de la fonction process_post
Modifiez votre programme selon les consignes données et compilez le
Exécutez le programme dans le simulateur et observez le comportement
![]() |
Observez vous une différence dans le temps de prise en compte de la nouvelle valeur ?
|