/******************************************************************** * Copyright (C) 2018 by UCBL / LIP * * Initial author: Matthieu Moy * ********************************************************************/ #include #include #include #include #include #include #include #define NB_THREADS 100 #define NB_PLACES 15 class StationVelov { public: int poser_velov() { std::unique_lock l(m); while (nb_place_libre <= 0) { c_plein.wait(l); } int place = -1; for (int i = 0; i < NB_PLACES; i++) { if (place_libre[i]) { place = i; place_libre[i] = false; nb_place_libre--; break; } } assert(place >= 0); c_vide.notify_all(); return place; } int essayer_poser_velov() { std::unique_lock l(m); if (nb_place_libre <= 0) { return -1; } int place = -1; for (int i = 0; i < NB_PLACES; i++) { if (place_libre[i]) { place = i; place_libre[i] = false; nb_place_libre--; break; } } assert(place >= 0); c_vide.notify_all(); return place; } int prendre_velov() { std::unique_lock l(m); while (nb_place_libre >= NB_PLACES) { c_vide.wait(l); } int place = -1; for (int i = 0; i < NB_PLACES; i++) { if (!place_libre[i]) { place = i; place_libre[i] = true; nb_place_libre++; break; } } assert(place >= 0); c_plein.notify_all(); return place; } int essayer_prendre_velov() { std::unique_lock l(m); if (nb_place_libre >= NB_PLACES) { return -1; } int place = -1; for (int i = 0; i < NB_PLACES; i++) { if (!place_libre[i]) { place = i; place_libre[i] = true; nb_place_libre++; break; } } assert(place >= 0); c_plein.notify_all(); return place; } private: bool place_libre[NB_PLACES] = {false}; int nb_place_libre = 0; std::mutex m; std::condition_variable c_vide, c_plein; }; StationVelov s; void robot(int n) { for (int i = 0; i < 1000; i++) { if (rand() % 2 == 0) usleep(100); if (rand() % 2 == 0) { printf("%d: essaye prend\n", n); if (s.essayer_prendre_velov() == -1) { printf("%d: raté\n", n); continue; } } else { printf("%d: prend\n", n); s.prendre_velov(); } printf("%d: pris\n", n); if (rand() % 2 == 0) usleep(100); printf("%d: pose\n", n); s.poser_velov(); printf("%d: posé\n", n); } } int main() { srand(time(NULL)); std::vector tab; for (int i = 0; i < NB_THREADS; i++) { tab.push_back(std::thread(robot, i)); } for (std::thread &t: tab) { t.join(); } }