Semaphore and Mutex in C

Asked

Viewed 667 times

3

I have the following problem:

A LAN house with 3 pcs, I will insert an X value in the terminal that will be the number of clients arriving in the lan house, customers can only use the Pcs that are unoccupied, in case you are busy go to a waiting room, this waiting room supports 15 customers. If you don’t have a pc available or room in the waiting room, the customer simply leaves...

1) Yes, it is a college job;
2) No, I don’t want anything settled by hand;
3) I just need a help to understand how to solve this problem....

I’ve been reading a lot about semaphore, mutex, threads, but still what needs to be done is still kind of obscure to me.

Here is the very little I wrote trying to solve this problem. Any tip is very welcome !

    #include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ROOM_SIZE 15

sem_t queue, pc;
int room [ROOM_SIZE]; // 0 -> livre  |  != 0  -> ocupado
int pcsAvaliable = 3, roomAvaliable = ROOM_SIZE;
int computers[3] = {0, 0, 0}; // 0 -> livre  |  1 -> ocupado

struct Client{
    int id;
};

int check_computer()
{
    int i;
    for(i=0; i<3; i++)
    {
        if(computers[i] == 0)
            return i;
    }
    return -1;
}

void insert_waitingRoom(int idClient)
{
    int i;
    for(i=0; i< ROOM_SIZE; i++)
    {
        if(room[i] == 0)
            room[i] = idClient;
    }
}


void* Lan(void* arg)
{
    struct Client *cli = (struct Client*) arg;

    int idPC;
    int idClient = cli->id;
    if(pcsAvaliable > 0)
    {
        sem_wait(&pc);
        pcsAvaliable--;
        idPC = check_computer();
        if(idPC >= 0)
        {
            computers[idPC] = 1;
            printf("Cliente %d pegou pc %d\n", idClient, idPC);
            usleep( (   (rand() % 11) + 80) * 1000);

            computers[idPC] = 0;
            printf("Cliente %d deixou o pc %d\n", idClient, idPC);
            pcsAvaliable++;
        }
        sem_post(&pc);
        sem_post(&queue);

    }
    else
    {
        //Quando os pcs estão ocupados, o cliente fica na sala de espera.
        //Mas ele fica lá eternamente. Tem que fazer ele tentar entrar no PC e não o novo processo que vem da main.
        if(roomAvaliable >0)
        {
            sem_wait(&queue);
            roomAvaliable--;
            printf("Cliente %d foi posto na sala de espera !\n", idClient);
            insert_waitingRoom(idClient);
            while(pcsAvaliable <= 0)
            {
                //tentar acessar pc
            }


        }
    }

}


int main(int argc, char const *argv[])
{
    int i=0, j=1;

    if(argc > 1)
    {
        int numClients = atoi(argv[1]);
        sem_init(&pc, 0, 3);
        sem_init(&queue, 0, 15);
        pthread_t clients[numClients];

        //Create Clients
        for(i=0; i< numClients; i++)
        {
            struct Client* cli = (struct Client*) malloc(sizeof(*cli));
            cli->id = i;

            pthread_create(&clients[i], NULL, Lan, (void*)cli);
            usleep( (   (rand() % 5) + 1) * 10000);
        }
    }
    else
        printf("Por favor. Informe o número de clientes");

    sem_destroy(&pc);
    pthread_exit(NULL);
    return 0;
}

1 answer

2

First my suggestion is to create a 3 PC spaces (or a char 3-space).

typedef struct{
    char *nome;
    char status : 2; // 0 - livre | 1 - ocupado
    // O ": 2" especifica que em status, o valore máximo será
    // 1 e o mínimo será 0 (os valores atribuídos recebem % 2)
}PC;

With this structure it will be possible to know which PC will be unoccupied when you write the name.

The method Lan has a parameter, and nothing more correct than to use it. In this method, the only thing that will happen is to mark the PC as unoccupied and/or write the name of PC.

The amount of Threads required for the system is the amount of Pcs that the lan-house possesses.

Customers who extrapolate ROOM_SIZE+3 do not need to be included in the loop, as they will go away anyway.

The main will monitor the number of people still on hold and check which Pcs are available, so whenever a PC is free, will already start a new Thread for this PC.

The code works normal without the pthread_join, but it’s okay to use it, if you’re going to use it, leave it just below the pthread_create.

  • Thanks for your help. My biggest problem is using traffic lights, I can’t get customers to use all 3 Pcs and stand in line. They take turns between 0,1,2, 2, 2, 2, 2,2 (it is eternally in and out of 2). : The

  • @Playhardgopro, if you need and/or are interested, I can put in the explanation the section where the traffic light is made to control the free Pcs

  • Hey. I updated my code, apparently (I think) I am managing to control the clients in the 3 pcs and are taking turns all the pcs (not only the 2 as it was before). But I even "insert" the client into the speech, but I can’t get him to dispute the computer again. The New client (coming from main), takes over the pc and the so-and-so stays in line forever. Could you take a look ?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.