ПОС/Лаб 5 2022

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

Група 1

Поставка

Допунити дату test5.c датотеку тако да се реши проблем спавајућег берберина. Берберин има салон. У салону шиша муштерије. Док нема муштерија у салону, берберин чека. Берберин шиша муштерије по реду којим су ушле у салон. Због здравствених прописа у салону могу бити највише две муштерије. Свака муштерија има јединствени идентификатор који добија приликом креирања. Тај идентификатор служи за опис активности (нпр. улазак у салон, приступање шишању, итд.).

Додати делове у датотеку test5.c који су потребни да би програм радио тражени посао. Постојећи код не сме се мењати. Дозвољено је користити pthreads нити и POSIX семафоре. Главна нит треба да чека док берберин и муштерије не заврше.

Пример једног излаза:

Ulazi u berbernicu 0
Sredjujem musteriju 0
Sredjena musterija 0
Izlazi iz berbernice 0
Ulazi u berbernicu 1
Sredjujem musteriju 1
Ulazi u berbernicu 2
Sredjena musterija 1
Izlazi iz berbernice 1
Sredjujem musteriju 2
Sredjena musterija 2
Izlazi iz berbernice 2
Ulazi u berbernicu 0
Sredjujem musteriju 0
Sredjena musterija 0
Izlazi iz berbernice 0
Ulazi u berbernicu 1
Sredjujem musteriju 1
Sredjena musterija 1
Izlazi iz berbernice 1
Ulazi u berbernicu 0
Sredjujem musteriju 0
Sredjena musterija 0
Izlazi iz berbernice 0
Ulazi u berbernicu 2
Sredjujem musteriju 2
Ulazi u berbernicu 1
Sredjena musterija 2
Izlazi iz berbernice 2
Sredjujem musteriju 1
Sredjena musterija 1
Izlazi iz berbernice 1
Ulazi u berbernicu 0
Sredjujem musteriju 0
Sredjena musterija 0
Izlazi iz berbernice 0
Ulazi u berbernicu 1
Sredjujem musteriju 1
Ulazi u berbernicu 2
Sredjena musterija 1
Izlazi iz berbernice 1
Sredjujem musteriju 2
Ulazi u berbernicu 0
Sredjena musterija 2
Izlazi iz berbernice 2
Sredjujem musteriju 0
Sredjena musterija 0
Izlazi iz berbernice 0
Ulazi u berbernicu 1
Sredjujem musteriju 1
Sredjena musterija 1
Izlazi iz berbernice 1
Ulazi u berbernicu 2
Sredjujem musteriju 2
Sredjena musterija 2
Izlazi iz berbernice 2
Ulazi u berbernicu 2
Sredjujem musteriju 2
Sredjena musterija 2
Izlazi iz berbernice 2

Решење

Овај задатак није решен. Помозите SI Wiki тако што ћете га решити.

Следеће решење је освојило 6/14 бодова и асистенти су оставили коментаре напоменуте испод.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define printThreadSafe(str,...) {\
    sem_wait(&mutexIspisi);\
    printf(str, __VA_ARGS__);\
    sem_post(&mutexIspisi);\
}

#define M (5)
#define N (3)

sem_t mutexIspisi;
sem_t Udji;
sem_t musterije;

static int ind=0;

void udjiUBerbernicu(int id) {
    sem_wait(&Udji); // Коментар: "kada da izadje? -2"
}

void* musterija(void *param) {
    int id = ind++ ; // Odrediti ID musterije
                     // Коментар: "nije thread safe -2"
    sem_wait(&musterije);
    for (int i = 0; i < M; i++) {
        sleep(id * 3 + rand()%10);
        printThreadSafe("Ulazi u berbernicu %d\n", id);
        udjiUBerbernicu(id);
        printThreadSafe("Izlazi iz berbernice %d\n", id);
        sleep(id * 3 + rand()%10);
    }
    free(param);
    sem_post(&musterije);
    return 0;
}

void podsisaj() {
    int id = ind ; // odrediti sledecu musteriji
                   // Коментар: "ovo treba da preda musterija koja udje -2"
    printThreadSafe("Sredjujem musteriju %d\n", id);
    sleep(3);
    printThreadSafe("Sredjena musterija %d\n", id);
}

void* berber(void* param) {
    for (int i = 0; i < M * N; i++) {
        // Коментар: "kada ima nekog? -2"
        podsisaj();
        sleep(1);
        sem_post(&Udji);
    }
    return 0;
}

int main() {
    pthread_t berberin, musterije[N];
    srand(time(0));
    sem_init(&mutexIspisi, 0, 1);
    // inicijalizacija ostalih semafora i niti
    sem_init(&Udji, 0, 2);
    sem_init(&musterije, 0, N);
    if (pthread_create(&berberin, 0, berber, 0)){
        perror(NULL);
        exit(1);
    }
    for (int i=0; i<N; i++) {
        if (pthread_create(&musterije[i], 0, musterija, 0)) {
            perror(NULL);
            exit(1);
        }
    }
    // kraj inicijalizacije
    // Sacekati sve niti
    pthread_join(berberin,0);
    for(int i=0; i<N; i++){
        pthread_join(musterije[i],0);
    }
    sem_close(&mutexIspisi);
    sem_destroy(&Udji);
    sem_destroy(&musterije);
    exit(0);
}