Esercizio programmazione concorrente in c

di il
2 risposte

Esercizio programmazione concorrente in c

Salve, sono nuovo nel Forum quindi spero di non infrangere nessuna regola.
Ho iniziato a studiare programmazione in c e mi trovo a dover risolvere questo esercizio di sincronizzazione e non so come procedere,
ho iniziato provando a scriverne una parte ma non sapendo ne se ho fatto bene fin qui ne come procedere.
Cio che devo fare è creare dei thread cliente che si metta in attesa di poter lavare i panni , azionando uno dei due thread lavatrice ed attendere che questa finisca il lavaggio, il cliente deve prendere sapone dal thread dispenser, mettere i panni nella lavatrice ed attendere che questa finisca il lavaggio, poi ritirare i panni e andarsene.
Qualcuno può aiutarmi?

#include <stdio.h>
#include <pthread.h>														//COMMENTI!!!
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>													//per SIGALARM della lavatrice

pthread_mutex_t distributoreNumeri;									//nome da cambiare!!
pthread_mutex_t turno;
pthread_mutex_t panni;
pthread_cond_t cambioTurno;
pthread_cond_t lavatrice1free;
pthread_cond_t lavatrice2free;


int ultimoBiglietto;
int display;
int clientiAlleLavatrici;
int saponeDispenser;
int saponeCliente;													//cambiare nomi, que e poi nel main!!

void Pthred_mutex_lock(pthread_mutex_t *mtx)
{
	int err;
	if((err = pthread_mutex_lock(mtx)) != 0)
	{
		errno = err;
		perror("lock");
		pthread_exit(&errno);
	}
}

void Pthred_mutex_unlock(pthread_mutex_t *mtx)
{
	int err;
	if((err = pthread_mutex_unlock(mtx)) != 0)
	{
		errno = err;
		perror("unlock");
		pthread_exit(&errno);
	}
}

void *cliente(void *_id)
{
	int id_cliente = (intptr_t)_id;
	int biglietto_cliente;
	int saponeCliente = 0;
	_Bool panniCliente = 1;								// 1 = vero, cliente ha i panni, 0 = falso, clienti non ha i panni

	while(1)
	{
		Pthread_mutex_lock(&distributoreNumeri);
		biglietto_cliente++;
		Pthread_mutex_unlock(&distributoreNumeri);

		fprintf(stdout, "[Cliente %d] ho preso il biglietto %d \n", id_cliente, biglietto_cliente);
		fflush(stdout);

		Pthread_mutex_lock(&turno);
		while(display != biglietto_cliente)
		{
			if(pthread_cond_wait(&cambioTurno, &turno) != 0)
			{
				fprintf(stderr,"pthread_cond_wait fallita!!\n");
				exit(EXIT_FAILURE);
			}
		}

		clientiAlleLavatrici++;
		if(clientiAlleLavatrici < 2)
		{
			display++;
			pthread_cond_broadcast(&cambioTurno);
		}
		Pthread_mutex_unlock(&turno);

		fprintf(stdout, "[cliente %d] si serve alle lavatrici con biglietto %d \n", id_cliente, biglietto_cliente);

		Pthread_mutex_lock(&turno);

		sleep(2);

		//prende sapone da dispenser
		saponeCliente++;
		saponeDispenser--;
		//mette i panni nella lavatrice ed avvia la lavatrice
		//attende la fine del lavaggio recupera i panni ed esce

		if(clientiAlleLavatrici == 2)
		{
			display++;
			pthread_cond_broadcast(&cambioTurno);
		}
		clientiAlleLavatrici--;

		fprintf(stdout, "[CLIENTE %d] esce dal negozio \n", id_cliente);
		fflush(stdout);

		Pthread_mutex_unlock(&turno);

	}

	pthread_exit(NULL);
	return NULL;
}

void *lavatrice(void *_id)
{
	return NULL;
}

void *dispenser(void *_id)
{
	while(1)
	{
		int maxSapone = 100;

		if(saponeDispenser < maxSapone)
		{
			for(int i=saponeDispenser; i<maxSapone; i++)						//prima o poi il dispenser sarà pieno
			{
				saponeDispenser++;
				sleep (4);
			}
		}
	}

	return NULL;
}

int main(void)
{

	pthread_t threadsClienti;
	pthread_t threadsLavatrici;
	pthread_t threadsDispenser;

	ultimoBiglietto = 0;
	display = 0;
	clientiAlleLavatrici = 0;
	saponeCliente = 0;
	saponeDispenser = 0;

	int num_clienti = 10;
	int num_lavatrici = 2;
	int num_dispenser = 1;

	if(pthread_mutex_init(&distributoreNumeri, NULL) != 0)
	{
		fprintf(stderr, "pthread_mutex_init fallita!!\n");
		exit(EXIT_FAILURE);
	}

	if(pthread_mutex_init(&turno, NULL) != 0)
	{
		fprintf(stderr, "pthread_mutex_init fallita!!\n");
		exit(EXIT_FAILURE);
	}

	if(pthread_cond_init(&cambioTurno, NULL) != 0)
	{
		fprintf(stderr, "pthread_cond_init fallita!!\n");
		exit(EXIT_FAILURE);
	}


	for(int i=0; i<num_clienti; i++)
	{
		if(pthread_create(&threadsClienti, NULL, cliente, (void *)(intptr_t)i) != 0)
		{
			fprintf(stderr, "pthread_create cliente fallita!!\n");
			exit(EXIT_FAILURE);
		}
	}

	for(int i=0; i<num_lavatrici; i++)
	{
		if(pthread_create(&threadsLavatrici, NULL, lavatrice, (void *)(intptr_t)i) != 0)
		{
			fprintf(stderr, "pthread_create lavatrice fallita!!\n");
			exit(EXIT_FAILURE);
		}
	}

	for(int i=0; i<num_dispenser; i++)
	{
		if(pthread_create(&threadsDispenser, NULL, dispenser, (void *)(intptr_t)i) != 0)
		{
			fprintf(stderr, "pthread_create dispenser fallita!!\n");
			exit(EXIT_FAILURE);
		}
	}

	/*
	while(1)
	{
		sleep(5);															// ciclo che aspetta 5 secondi e 
		fprintf(stdout, "[LAVATRICE %d] ha servito %d clienti\n", id_lavatrice display);		// stampa quale lavatrice ha servito i clienti
		fflush(stdout);														// da controllare!!!
	}
	*/

	return 0;

}

2 Risposte

  • Re: Esercizio programmazione concorrente in c

    Innanzitutto comincia a scrivere giusti i nomi delle funzioni, altrimenti non compila

    Hai scritto
    
    void Pthred_mutex_lock(pthread_mutex_t *mtx)
    
    void Pthred_mutex_unlock(pthread_mutex_t *mtx)
    
    Ma da come le chiami devono essere
    
    void Pthread_mutex_lock(pthread_mutex_t *mtx)
    
    void Pthread_mutex_unlock(pthread_mutex_t *mtx)
    
    Dopodiché sii specifico nelle domande. Cosa non ti torna di quello che hai scritto? Cosa ti aspetti? Cosa vorresti che accadesse?
    E' dura dare indicazioni su un programma intero, in multi-threading poi...
  • Re: Esercizio programmazione concorrente in c

    Intanto grazie per le correzioni!!
    ciò che non mi riesce è come impostare il cliente, credo di non aver sbagliato la gestione del turno dei clienti ma adesso dovrei scrivere cosa devono fare;
    in particolare vorrei che quando è il suo turno il cliente recuperi sapone dal dispenser, metta i panni nella lavatrice, la avvii, attenda la fine del "lavaggio" della lavatrice e che in fine recuperi i panni.
    Quello che ho pensato è di usare due variabili booleane, una in cliente ed una in lavatrice, per tenere traccia di quando il cliente ha i panni e di quando invece li ha la lavatrice e può cosi avviare il proprio "ciclo", non sò però come passare o recuperare variabili da un thread all'altro ne come far aspettare la fine dell'altro.
Devi accedere o registrarti per scrivere nel forum
2 risposte