Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <thread>
- #include <string>
- #include <vector>
- #include <mutex>
- #include <unistd.h>
- using namespace std;
- struct Barber {
- int sleeping = 1;
- int sleeping_time = 0;
- int client_id = -1;
- } ;
- struct Client {
- int look_position = -1;
- } ;
- //
- std::mutex sync_barbers_mutex;
- std::mutex sync_clients_mutex;
- std::mutex sync_queue_mutex;
- std::mutex log_mutext;
- std::vector<Barber> barbers(4);
- std::vector<Client> clients(50);
- int barbers_count = 0;
- int clients_count = 0;
- std::vector<int> clients_queue(20, -1);
- // IMPORTANTE! verificar se esta utilizando o mutex sync_barbers_mutex antes de chamar
- int check_barber() {
- int barber_id = 0;
- int max_sleep = -1;
- int best_barber_id = -1;
- for(auto &barber : barbers) {
- if(!barber.sleeping) {
- best_barber_id = barber_id;
- break;
- } else if(barber.client_id == -1 && barber.sleeping_time > max_sleep) {
- max_sleep = barber.sleeping_time;
- best_barber_id = barber_id;
- }
- barber_id++;
- }
- return best_barber_id;
- }
- //
- void client_process() {
- // Assign client
- sync_clients_mutex.lock();
- int id = clients_count++;
- log_mutext.lock();
- std::cout << "Cliente " << id << std::endl;
- log_mutext.unlock();
- sync_clients_mutex.unlock();
- // Reserva seu lugar caso seja possível
- int clients_count = 0;
- int position = -1;
- sync_queue_mutex.lock();
- for(int i=19; i>=0; i--) {
- if(clients_queue[i] == -1) {
- position = i;
- continue;
- }
- break;
- }
- // Encontrou um lugar
- if(position != -1) {
- clients_queue[position] = id;
- sync_barbers_mutex.lock();
- int best_barber_id = check_barber();
- sync_barbers_mutex.unlock();
- log_mutext.lock();
- if(position == 0 && best_barber_id != -1)
- std::cout << "Cliente " << id << " entrou na barbearia e ja vai se atendido." << std::endl;
- else if(position <= 9)
- std::cout << "Cliente " << id << " entrou na barbearia e esta esperando sentado na posição " << position << "." << std::endl;
- else
- std::cout << "Cliente " << id << " entrou na barbearia e esta esperando de pe na posição " << position << "." << std::endl;
- log_mutext.unlock();
- sync_queue_mutex.unlock();
- // Estava lotado
- } else {
- log_mutext.lock();
- std::cout << "Cliente " << id << " foi embora porque não tinha lugar para esperar." << std::endl;
- log_mutext.unlock();
- sync_queue_mutex.unlock();
- }
- //
- while(true) {
- // Verifica se existe algum barbeiro livre (O que esta acordado ou o que esta dormindo mais)
- if(position == 0) {
- sync_barbers_mutex.lock();
- int best_barber_id = check_barber();
- // Caso tenha encontrado algum barbeiro
- if(best_barber_id != -1) {
- // Retira cliente da fila
- sync_queue_mutex.lock();
- clients_queue[0] = -1;
- sync_queue_mutex.unlock();
- // Inicia corte de cabelo
- log_mutext.lock();
- std::cout << "Cliente " << id << " iniciou o corte de cabelo." << std::endl;
- log_mutext.unlock();
- barbers[best_barber_id].client_id = id;
- //
- sync_barbers_mutex.unlock();
- //
- break;
- }
- sync_barbers_mutex.unlock();
- } else {
- sync_queue_mutex.lock();
- for(int i=position; i>=0; i--) {
- if(clients_queue[i] == -1) {
- clients_queue[id] = -1;
- clients_queue[i] = id;
- position = i;
- log_mutext.lock();
- std::cout << "Cliente " << id << " ipulou para posição " << position << "." << std::endl;
- log_mutext.unlock();
- break;
- }
- }
- sync_queue_mutex.unlock();
- }
- //
- usleep(100000);
- //break;
- }
- log_mutext.lock();
- std::cout << "Cliente morreu" << std::endl;
- log_mutext.unlock();
- }
- int main()
- {
- std::vector<std::thread> clients_threads;
- // Main process
- for(int i=0; i<25; i++) {
- clients_threads.push_back(std::thread(&client_process));
- usleep(50000);
- //client.join();
- }
- while(clients_threads.size() > 0) {
- clients_threads.back().join();
- clients_threads.pop_back();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement