Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdlib>
- #include <fcntl.h>
- #include <string.h>
- #include <sys/mman.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <iostream>
- #include <cstdio>
- #include <atomic>
- #include <cstdio>
- #include <locale>
- #include <iomanip>
- #include <atomic>
- using namespace std;
- #define CUT_MIN_TIME 2
- #define CUT_MAX_TIME 5
- #define COME_MIN_TIME 1
- #define COME_MAX_TIME 3
- #define sh_mem "sm" // имя объекта разделяемой памяти
- struct Barbershop
- {
- sem_t customers; // в этом семафоре храним число ожидающих посетителей
- sem_t barbers; // семафор брадобрея
- int waiting;
- int chair_count; // количество свободных стульев
- int customer_count; // количество посетителей в день
- int serviced_customer_count; // количество обслуженных посетителей
- atomic_int _end; //перемнная, операции увеличения(уменьшения) над которой будт неделимы для всех потоков
- };
- //объект струткуры
- Barbershop* barbershop;
- int come_time; // время прибытия посетителя
- void show_message(int threadid, char* person, char* msg, int w = 0)
- {
- cout.fill('.');
- cout << '[' << person << setw(w) << " " << threadid << "] " << msg << " " <<endl;
- }
- int barber()
- {
- while(barbershop->_end != -1)
- {
- // если значение семофора <0, то он блокируется, пока один из потоков не вызовет post
- sem_wait(&barbershop->customers); // ждем посетителей
- barbershop->waiting--;
- int cut_time = rand() % (CUT_MAX_TIME - CUT_MIN_TIME) + CUT_MIN_TIME;
- show_message(cut_time, (char*)"БРАДОБРЕЙ", (char*)"бреет бороду клиенту", 7);
- sleep(cut_time); // обслуживаем посетителя
- //Эта функция увеличивает значение семафора и разблокирует ожидающие потоки
- sem_post(&barbershop->barbers); // просыпаемся
- barbershop->serviced_customer_count++;
- }
- return 0;
- }
- int customer(int id)
- {
- barbershop->_end++;
- show_message(id, (char*)"КЛИЕНТ", (char*)"пришел.", 10);
- if(barbershop->waiting < barbershop->chair_count) // посетитель уходит если нет свободных мест
- {
- barbershop->waiting++;
- cout << "Ждущих посетителей: " << barbershop->waiting << endl;
- show_message(id, (char*)"КЛИЕНТ", (char*)"ждет.", 10);
- sem_post(&barbershop->customers);
- sem_wait(&barbershop->barbers); // ждем когда брадобрей освободится
- show_message(id, (char*)"КЛИЕНТ", (char*)"уходит довольным", 10);
- }
- else
- {
- show_message(id, (char*)"КЛИЕНТ", (char*)"ушел небритым.", 10);
- }
- barbershop->_end--;
- return 0;
- }
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL, "Russian");
- shm_unlink(sh_mem);
- // создание/открытие объекта разделяемой памяти
- int fd = shm_open(sh_mem, O_RDWR | O_CREAT, 0777);
- // отображение разделяемой памяти
- barbershop = (Barbershop*) mmap(0, sizeof(Barbershop), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- ftruncate(fd, sizeof(Barbershop*));
- // обнуляем всю разделяемую память
- memset((void*)barbershop, 0, sizeof(Barbershop));
- barbershop->customer_count = atoi(argv[1]);
- barbershop->chair_count = atoi(argv[2]);
- sem_init(&barbershop->customers, 1, 0);
- sem_init(&barbershop->barbers, 1, 0);
- if (fork()>0)
- return barber();
- for (int i = 0; i < barbershop->customer_count; ++i)
- {
- come_time = rand() % (COME_MAX_TIME - COME_MIN_TIME) + COME_MIN_TIME;
- sleep(come_time);
- if (fork()>0)
- return customer(i+1);
- }
- while(barbershop->_end);
- barbershop->_end = -1;
- cout << "--------- Статистика рабочего дня -----------" << endl;
- cout << "Количество побритых клиентов: " << barbershop->serviced_customer_count << endl;
- shm_unlink(sh_mem);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement