Thread POSIX

Ce laboratoire présente la programmation des threads POSIX en langage C. Il permet d'apprendre à créer des threads, à gérer leur exécution concurrente, puis à synchroniser leur ordre d'exécution à l'aide de sémaphores.

D'après le document Thread POSIX

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Thread POSIX

Document source

Thread POSIX

Programming · PDF · 3 pages

Afficher l'aperçu du document

Consulter le document original →

Ce laboratoire présente la programmation des threads POSIX en langage C. Il permet d'apprendre à créer des threads, à gérer leur exécution concurrente, puis à synchroniser leur ordre d'exécution à l'aide de sémaphores. Pour réaliser ce TP, un environnement de développement C avec support POSIX (Linux, macOS, ou autre système compatible) est nécessaire, ainsi que la connaissance des bases du langage C et des threads.

Objectifs

  • Créer et lancer des threads POSIX en C.
  • Comprendre le comportement concurrent des threads.
  • Utiliser pthread_create, pthread_exit et pthread_join.
  • Synchroniser l'exécution des threads avec des sémaphores POSIX.
  • Contrôler l'ordre d'affichage des threads sans utiliser sleep pour la synchronisation.

Prérequis et installation

  • Un compilateur C compatible POSIX (gcc recommandé).
  • Bibliothèques pthread et semaphore disponibles (généralement incluses dans les distributions Linux).
  • Connaissances de base en programmation C et notions sur les threads.
  • Commande de compilation avec l'option -pthread pour lier la bibliothèque pthread.

Création de threads

Dans ce premier exercice, vous devez programmer et compiler un exemple simple de création de thread vu en cours. Il faut veiller à utiliser les options de compilation correctes, notamment -pthread.

Exécutez ce programme et observez son comportement. Vous devriez voir que les threads s'exécutent concurremment, affichant leurs messages indépendamment.

Exercice 2 : Lancement de plusieurs threads exécutant la même fonction

Voici la fonction que chaque thread doit exécuter :

void *ma_nouvelle_sequence_control (void * arg)
{
  int i;
  for (i = 0 ; i < 10 ; i++) {
    printf ("Thread %s: %d\n", (char*)arg, i);
    sleep (1);
  }
  pthread_exit (0);
}

Réalisez un programme C qui lance 3 threads exécutant cette fonction, chacun recevant un nom différent en argument. Utilisez les fonctions pthread_create, pthread_exit et pthread_join.

Exécutez votre programme et observez que les trois threads s'exécutent simultanément, affichant leurs messages en alternance selon la planification du système.

Introduction à la synchronisation des threads

Exemple sans synchronisation

Voici un programme simple qui crée deux threads :

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

void *thread1_process (void * arg)
{
  sleep (1);
  printf ("[2]\n");
  pthread_exit (0);
}

void *thread2_process (void * arg)
{
  sleep (5);
  printf ("[1]\n");
  pthread_exit (0);
}

int main (int argc, char **argv)
{
  pthread_t th1, th2;
  void *ret;

  if (pthread_create (&th1, NULL, thread1_process, NULL) < 0)
  {
    fprintf (stderr, "pthread_create error\n");
    exit (1);
  }

  if (pthread_create (&th2, NULL, thread2_process, NULL) < 0) {
    fprintf (stderr, "pthread_create error\n");
    exit (1);
  }
  (void)pthread_join (th1, &ret);
  (void)pthread_join (th2, &ret);

  return 0;
}

Exécutez ce programme. Vous constaterez que l'affichage est :

[2]
[1]

car le thread1 affiche après 1 seconde et le thread2 après 5 secondes.

Contrôler l'ordre d'exécution avec un sémaphore

Pour forcer un ordre d'exécution, on utilise un sémaphore POSIX :

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

static sem_t my_sem;

void *thread1_process (void * arg)
{
  sleep (1);
  sem_wait (&my_sem);
  printf ("[2]\n");
  pthread_exit (0);
}

void *thread2_process (void * arg)
{
  sleep (5);
  printf ("[1]\n");
  sem_post (&my_sem);
  pthread_exit (0);
}

int main (int ac, char **av)
{
  pthread_t th1, th2;
  void *ret;

  sem_init (&my_sem, 0, 0);

  if (pthread_create (&th1, NULL, thread1_process, NULL) < 0) {
    fprintf (stderr, "pthread_create error\n");
    exit (1);
  }
  if (pthread_create (&th2, NULL, thread2_process, NULL) < 0) {
    fprintf (stderr, "pthread_create error\n");
    exit (1);
  }
  (void)pthread_join (th1, &ret);
  (void)pthread_join (th2, &ret);
}

Exécutez cette version. L'affichage sera :

[1]
[2]

car le thread2 libère le sémaphore avec sem_post après son affichage, permettant au thread1 d'afficher ensuite.

La variable my_sem sert donc de barrière de synchronisation, contrôlant l'ordre d'exécution des threads.

Cas pratique : affichage ordonné de plusieurs threads

Réalisez un programme qui lance 10 threads numérotés de 0 à 9. Chaque thread doit afficher son numéro.

  • L'ordre de création des threads est croissant (de 0 à 9).
  • L'affichage doit se faire dans l'ordre décroissant (de 9 à 0).
  • Il ne faut pas utiliser sleep() pour la synchronisation temporelle.

Pour cela, vous pouvez utiliser des sémaphores ou une autre méthode de synchronisation pour forcer l'ordre d'affichage inverse à celui de création.

Résultats attendus

  • Dans l'exercice de création simple, les threads affichent leurs messages en parallèle, sans ordre garanti.
  • Dans l'exemple avec sémaphore, l'ordre d'affichage est contrôlé et correspond à la séquence attendue.
  • Dans le cas pratique, les numéros des threads doivent s'afficher dans l'ordre décroissant de 9 à 0, malgré une création dans l'ordre croissant.

Pièges courants

  • Oublier d'utiliser l'option -pthread lors de la compilation, ce qui provoque des erreurs de linkage.
  • Ne pas utiliser pthread_join pour attendre la fin des threads, ce qui peut entraîner la fin prématurée du programme principal.
  • Utiliser sleep() pour synchroniser l'ordre d'exécution, ce qui est non fiable et dépendant du système.
  • Ne pas initialiser correctement le sémaphore avec sem_init.
  • Ne pas appeler sem_post dans le thread qui doit libérer la barrière, bloquant ainsi les autres threads.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions