Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <getopt.h>
- #include <list>
- #include <queue>
- #include <semaphore.h>
- #include <zconf.h>
- #include <cstdlib>
- //using namespace std;
- #define MAX 20 //max klientow
- void *client(void *param);
- void *barber(void *number);
- sem_t chairs_mutex;
- sem_t sem_client;
- sem_t sem_barber;
- int Clients = 0;
- int num_chairs = 0;
- int clientWait = 2;
- int chairs_total;
- std::list<int> queue;
- std::list<int> res;
- int in;
- bool DebugFlag = false;
- bool Done = false;
- int main(int argc, char **argv) {
- int opt;
- int option_index = 0;
- static struct option long_options[] = {
- {"debug", no_argument, 0, 0},
- {"cl", required_argument, 0, 1},
- {"ch", required_argument, 0, 2}
- };
- //obsluga przelacznikow
- while ((opt = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
- switch (opt) {
- case 0:
- DebugFlag = true;
- break;
- case 1:
- Clients = atoi(optarg);
- break;
- case 2:
- num_chairs = atoi(optarg);
- break;
- case '?':
- break;
- default:
- abort();
- }
- }
- int Number[Clients];
- chairs_total = num_chairs;
- int i;
- pthread_t barberid;
- for (i = 0; i < Clients; i++) {
- Number[i] = i + 1;
- }
- pthread_t clientids[MAX];
- //inicjalizacja semaforów i mutexa
- int sem1 = sem_init(&chairs_mutex, 0, 1);
- if(sem1 == -1)
- {
- fprintf(stderr,"Error -sem_init() return code: %d\n",sem1);
- exit(EXIT_FAILURE)
- }
- int sem2 = sem_init(&sem_client, 0, 0);
- if(sem2 == -1)
- {
- fprintf(stderr,"Error -sem_init() return code: %d\n",sem2);
- exit(EXIT_FAILURE)
- }
- int sem3 = sem_init(&sem_barber, 0, 0);
- if(sem3 == -1)
- {
- fprintf(stderr,"Error -sem_init() return code: %d\n",sem3);
- exit(EXIT_FAILURE)
- }
- int code = 0;
- //tworzenie wątku fryzjera
- code = pthread_create(&barberid, NULL, barber, NULL);
- if(code)
- {
- fprintf(stderr,"Error -pthread_create() Barber return code: %d\n",code);
- exit(EXIT_FAILURE)
- }
- //twadzenie wątku klientów
- for (i = 0; i < Clients; i++) {
- code = pthread_create(&clientids[i], NULL, client, &Number[i]);
- if(code)
- {
- fprintf(stderr,"Error -pthread_create() Clients return code: %d\n",code);
- exit(EXIT_FAILURE)
- }
- }
- //Dodanie joina dla każdego wątku klienta aby czekał na jego zakończenie
- for (int j = 0; j < Clients; ++j) {
- code = pthread_join(clientids[j], NULL);
- if(code)
- {
- fprintf(stderr,"Error -pthread_join() return code: %d\n",code);
- exit(EXIT_FAILURE)
- }
- }
- //Wszystkie watki klientow przerobione
- Done = true;
- //Wybudzenie fryzjera
- sem_post(&sem_barber);
- //Poczekanie aż wątek fryzjera się skończy
- pthread_join(barberid, NULL);
- exit(0);
- }
- void *barber(void *param) {
- int worktime;
- while (!Done) {
- //poczekaj na klientów aż będą dostępni
- sem_wait(&sem_client);
- //poczekaj na dostęp do krzeseł
- sem_wait(&chairs_mutex);
- //zwiększ liczbę dostępnych krzeseł
- num_chairs += 1;
- //ustawienie zdjęcie klienta z kolejki i ustawienie go jako w gabiniecie
- if (!queue.empty()) {
- in = queue.back();
- queue.pop_back();
- }
- std::cout << "Res: " << res.size() << " WRoom: " << queue.size() << "/" << chairs_total << " [in: "
- << in << "]"
- << std::endl;
- if (DebugFlag) {
- //Wypisanie klientow w kolejce
- std::cout << "Queue size " << queue.size() << std::endl;
- if (!queue.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el:queue)
- std::cout << "Wątek " << el << std::endl;
- //Wypisanie klientów którzy zrezygnowali
- std::cout << "Res size " << res.size() << std::endl;
- if (!res.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el2:res)
- std::cout << "Wątek: " << el2 << std::endl;
- }
- //sygnał dla klienta, że fryzjer jest wolny
- sem_post(&sem_barber);
- //zdjęcie blokady z liczby krzeseł
- sem_post(&chairs_mutex);
- //generuje losowy czas ścinania włosów od 1 do 4 sec
- worktime = (rand() % 4) + 1;
- //ścinanie włosów
- sleep(worktime);
- //ustawienie obecnego clienta na brak
- in = 0;
- std::cout << "Res: " << res.size() << " WRoom: " << queue.size() << "/" << chairs_total << " [in: "
- << in << "]"
- << std::endl;
- if (DebugFlag) {
- //Wypisanie klientow w kolejce
- std::cout << "Queue size " << queue.size() << std::endl;
- if (!queue.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el:queue)
- std::cout << "Wątek " << el << std::endl;
- //Wypisanie klientów którzy zrezygnowali
- std::cout << "Res size " << res.size() << std::endl;
- if (!res.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el2:res)
- std::cout << "Wątek: " << el2 << std::endl;
- }
- }
- }
- void *client(void *number) {
- int *num = (int *) number;
- int waittime;
- //losowy czas "dotarcia" do salonu
- waittime = (rand() % clientWait) + 1;
- sleep(waittime);
- //poczekaj na dostęp do liczby krzeseł
- sem_wait(&chairs_mutex);
- //jeśli nie ma krzeseł
- if (num_chairs <= 0) {
- //Dodanie do listy nie przyjetych klientow
- res.push_back(*num);
- std::cout << "Res: " << res.size() << " WRoom: " << queue.size() << "/" << chairs_total << " [in: "
- << in
- << "]" << std::endl;
- if (DebugFlag) {
- //Wypisanie klientow w kolejce
- std::cout << "Queue size " << queue.size() << std::endl;
- if (!queue.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el:queue)
- std::cout << "Wątek " << el << std::endl;
- //Wypisanie klientów którzy zrezygnowali
- std::cout << "Res size " << res.size() << std::endl;
- if (!res.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el2:res)
- std::cout << "Wątek: " << el2 << std::endl;
- }
- //zdjęcie blokady z krzeseł
- sem_post(&chairs_mutex);
- } else {
- //zmniejsz ilość wolnych miejsc
- num_chairs -= 1;
- //Dodanie do kolejki
- queue.push_back(*num);
- std::cout << "Res: " << res.size() << " WRoom: " << queue.size() << "/" << chairs_total << " [in: "
- << in
- << "]" << std::endl;
- if (DebugFlag) {
- //Wypisanie klientow w kolejce
- std::cout << "Queue size " << queue.size() << std::endl;
- if (!queue.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el:queue)
- std::cout << "Wątek " << el << std::endl;
- //Wypisanie klientów którzy zrezygnowali
- std::cout << "Res size " << res.size() << std::endl;
- if (!res.empty())
- std::cout << "Jej zawartość: " << std::endl;
- for (auto el2:res)
- std::cout << "Wątek: " << el2 << std::endl;
- }
- //sygnał, że klient jest gotowy
- sem_post(&sem_client);
- //zdjęcie blokady z krzeseł
- sem_post(&chairs_mutex);
- //czekanie na fryzjera
- sem_wait(&sem_barber);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement