Adloun

Corrigé X-ENS 2026 Informatique C MPI — Partie III (Q13 à Q14) : Programmation multi-threads en C

Sujet officiel du concours X-ENS, session 2026, épreuve Informatique C MPI. Corrigé rédigé par Ibrahim Alame.

Sujet officiel (PDF, site du concours)

Énoncé

Les en-têtes (dont <pthread.h>) sont implicitement inclus. Fonctions de la bibliothèque pthread rappelées par le sujet (figure 4) : pthread_create lance un thread exécutant start_routine(arg), pthread_join attend sa fin (second argument toujours NULL), pthread_attr_init initialise des attributs par défaut.


int pthread_attr_init(pthread_attr_t *attr);
int pthread_create(pthread_t *pthread,
                   pthread_attr_t *attr,
                   void *(*start_routine)(void *),
                   void *arg);
int pthread_join(pthread_t pthread, void **retval);

Programme de la figure 5 (une fonction max sur deux int est supposée fournie) :


int m = -1;

void* max2(void* pair) {
  int m1 = ((int*)pair)[0];
  int m2 = max(m1, ((int*)pair)[1]);
  int m3 = max(m2, m);
  m = m3;
  return NULL;
}

int main() {
  int array[4] = {10, 20, 30, 40};
  /* Attributs par défaut des threads */
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  /* Création des threads */
  pthread_t thread1, thread2;
  pthread_create(&thread1, &attr, max2, array);
  pthread_create(&thread2, &attr, max2, &(array[2]));
  /* Attente de fin et affichage du résultat */
  pthread_join(thread1, NULL);
  pthread_join(thread2, NULL);
  printf("m == %d\n", m);
}

Q13. a. Affichages possibles, et comment chacun s'obtient. b. Correction canonique (description de haut niveau des lignes à insérer), valable pour toutes valeurs positives du tableau.

Globales : const int nb_threads, const int items_per_thread, int m (initialisé à ), max_item ; void* local_max(void* a) traite, comme max2, les items_per_thread entiers positifs à partir de l'adresse a.
Q14. Écrire main : allouer sur le tas array de nb_threads*items_per_thread entiers, les initialiser par rand()%max_item, lancer nb_threads threads exécutant local_max sur les sous-tableaux commençant aux indices k*items_per_thread, afficher m quand tous ont terminé ; aucune fuite de mémoire (les accès concurrents ne sont pas à régler).

Corrigé

Q13. a. Le thread 1 calcule m1 = 10, m2 = 20, puis m3 = max(20, m) ; le thread 2 calcule m1 = 30, m2 = 40, puis m3 = max(40, m). Seules les lignes 6 (lecture de m) et 7 (écriture de m) touchent la variable partagée ; comme main attend les deux threads avant d'afficher, l'affichage porte sur la valeur écrite en dernier. On distingue selon l'ordre des lectures et des écritures :

Aucune autre valeur n'est possible : m final est la valeur m3 d'un des threads, et pour le thread 1, pour le thread 2 (et est exclu, les deux threads ayant écrit avant l'affichage). Exécuté : l'énumération des entrelacements des huit instructions (instructions supposées atomiques, comme en partie IV) donne exactement les valeurs finales .

b. La façon canonique est l'exclusion mutuelle par un verrou (mutex) : la lecture de m et l'écriture qui en dépend (lignes 6 et 7) forment une section critique. On insère :

100 % gratuit

La suite du corrigé est sur Adloun

Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.

Voir le corrigé complet, gratuitement

Inscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.

Toutes les parties de l'épreuve

Corrigé complet gratuit →