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;
}
|