QNX – Illustration 00

Le code proposé à droite est celui de l'illustration 00 proposé dans le document remis en classe.

Quelques liens pour en savoir plus sur des outils clés de cet exemple :

#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
using namespace std;
class Autoverrou {
   pthread_mutex_t &m;
public:
   Autoverrou(const Autoverrou &) = delete;
   Autoverrou& operator=(const Autoverrou &) = delete;
   Autoverrou(pthread_mutex_t &m) : m(m) {
      pthread_mutex_lock(&m);
   }
   ~Autoverrou() {
      pthread_mutex_unlock(&m);
   }
};
class Stats {
   int nbsrc = 100,
       nbdest = 0,
       nbconvoyeur = 0;
   bool fin = false;
   pthread_mutex_t m;
public:
   Stats() = default;
   void mettre_sur_convoyeur() {
      --nbsrc;
      Autoverrou av(m);
      ++nbconvoyeur;
   }
   void retirer_du_convoyeur() {
      {
         Autoverrou av(m);
         --nbconvoyeur;
      }
      ++nbdest;
   }
   void finir() {
      fin = true;
   }
   bool doit_finir() const volatile {
      return fin;
   }
   bool source_vide() const volatile {
      return !nbsrc;
   }
   bool convoyeur_vide() const volatile {
      return !nbconvoyeur;
   }
   friend ostream& operator<<(ostream&, const Stats&);
};
ostream& operator<<(ostream &os, const Stats &s) {
   return os << "Nb. fraises au debut: " << s.nbsrc << '\n'
             << "Nb. fraises sur le convoyeur: " << s.nbconvoyeur << '\n'
             << "Nb. fraises a la fin:" << s.nbdest;
}
void *ajouter_fraise(void *p) {
   auto &stats = *static_cast<Stats *>(p);
   while (!stats.doit_finir())
      if (!stats.source_vide())
         stats.mettre_sur_convoyeur();
  return nullptr;
}
void *enlever_fraise(void * p) {
   auto &stats = *static_cast<Stats *>(p);
   while (!stats.doit_finir())
       if (!stats.convoyeur_vide())
          stats.retirer_du_convoyeur();
   return nullptr;
}
int main() {
   int erreur;
   pthread_t thA, thB;
   Stats stats;
   erreur = pthread_create(&thA, 0, ajouter_fraise, &stats);
   if (erreur) {
      cerr << "Erreur, creation de ajouter_fraise, code " << erreur << '\n';
      exit(-1);
   }
   erreur = pthread_create(&thB, 0, enlever_fraise, &stats);
   if (erreur) {
      cerr << "Erreur, creation de enlever_fraise, code " << erreur << '\n';
      exit(-1);
   }
   cout << "Pressez une touche..." << endl;
   char c;
   cin.get(c);
   stats.finir();
   int *resultat;
   erreur = pthread_join(thB, reinterpret_cast<void **>(&resultat));
   if (erreur) {
      cerr << "Erreur, attente de enlever_fraise, code " << erreur << '\n';
      exit(-1);
   }
   erreur = pthread_join(thA, reinterpret_cast<void **>(&resultat));
   if (erreur) {
      cerr << "Erreur, attente de ajouter_fraise, code " << erreur << '\n';
      exit(-1);
   }
   cout << stats << endl;
}

Valid XHTML 1.0 Transitional

CSS Valide !