/* Programma di esempio di un client e di un server * sfruttando i thread e i semafori privati. */ #include #include #include #include #include /* Lunghezza massima del buffer */ #define LUN 40 /* Numero di client che viene generato */ #define NUM_CLIENT 30 struct{ /* buffer che conterra' la stringa */ char buffer[LUN]; /* semaforo di mutua esclusione */ sem_t mutex; /* Semaforo privato su cui si blocca il client */ sem_t *private; /* Puntatore alla zona in cui verra' messo il risultato */ char *risultato; }shared; sem_t richiesta; /* Forward declaration */ void *client(void *); void *server(void *); void *realServer(void *); int main(void) { pthread_t clientID[NUM_CLIENT], serverID; int res, i, j; /* Fase di inzializzazione delle strutture dati */ /* Ogni stringa C deve terminare con 0!!!!! */ shared.buffer[0] = 0; /* Fine della fase di inizializzazione delle strutture dati */ /* Fase di inizializzazione dei semafori */ if (sem_init(&shared.mutex, 0, 1) == -1) { printf("Non sono riuscito ad inizializzare shared.mutex\n"); return 1; } if (sem_init(&richiesta, 0, 0) == -1) { printf("Non sono riuscito ad inizializzare shared.mutex\n"); return 1; } /* Ora inizia la fase di creazione dei thread */ pthread_setconcurrency(1+2*NUM_CLIENT); /* Come prima cosa creo il server */ res = pthread_create(&serverID, NULL, server, NULL); if (res != 0) { printf("Non ho potuto creare il server \n"); exit(-1); } for(i=0; i=0; i--) { risu[len-1-i] = buf[i]; } risu[len] = 0; /* A questo punto perdo un poco di tempo */ for(j=0; j<20000000; j++); sem_post(priv); return NULL; } /* Codice dei vari client */ void *client(void *in) { char risu[LUN]; sem_t priv; risu[0] = 0; if (sem_init(&priv, 0, 0) == -1) { printf("Non sono riuscito ad inizializzare un semaforo privato\n"); pthread_exit(NULL); } sem_wait(&shared.mutex); shared.risultato = risu; sprintf(shared.buffer, "thread numero %d", (int)pthread_self()); shared.private = &priv; sem_post(&richiesta); sem_wait(&priv); printf("Thread %d -- Risultato = %s\n", (int)pthread_self(), risu); return NULL; }