codice:
#define _GNU_SOURCE
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <math.h>
#include <pthread.h>
#define SIZE 10
int main(int argc, char *argv[]){
int err;
if(argc != 4){//Faccio i controlli e assegno gli argomenti
fprintf(stderr,"Non ci sono i 4 elementi richiesti!\n\n\tUso:\t %s nomeFile numeroFile numeroThread\n\n",argv[0]);
exit(1);
}
if((argv[2] || argv[3]) < 0){
fprintf(stderr,"Ho bisogno di numeri positivi!\n");
exit(1);
}
int M = atoi(argv[2]);
int N = atoi(argv[3]);
char *nomeFile = argv[1];
int *buffer;//dichiaro variabili
int *interi;
FILE *f = fopen(nomeFile, "r");
int numero;
int linee = 0;
pid_t pid;
int indiceC = 0;
int *indiceP;
int shmid1 = shmget(IPC_PRIVATE, SIZE*(sizeof(int)), 0600);//inizializzo buffer condiviso
if(shmid1 == -1)puts("Errore nella creazione buffer condiviso!\n");
buffer = shmat(shmid1, NULL, 0);
puts("Ho inizializzato il buffer condiviso\n");
while(fscanf(f, "%d", &numero) != EOF){//conto numeri nel file
linee+=1;
}
rewind(f);
int shmid2 = shmget(IPC_PRIVATE, linee*(sizeof(int)), 0600);//inizializzo array di interi condiviso
if(shmid2 == -1)puts("Errore nella creazione array di interi condiviso!\n");
interi = shmat(shmid2, NULL, 0);
puts("Ho inizializzato l'array di interi condiviso\n");
int shempty = shmget(IPC_PRIVATE, sizeof(sem_t), 0600);//creo memoria per semafori
if(shempty == -1)puts("Errore nella creazione semaforo empty condiviso!\n");
int shfull = shmget(IPC_PRIVATE, sizeof(sem_t), 0600);
if(shfull == -1)puts("Errore nella creazione semaforo full condiviso!\n");
int shmutex = shmget(IPC_PRIVATE, sizeof(pthread_mutex_t), 0600);
if(shmutex == -1)puts("Errore nella creazione mutex condiviso!\n");
puts("Ho creato i semafori condivisi\n");
sem_t *empty = (sem_t *) shmat(shempty, NULL, 0);//associo i semafori
sem_t *full = (sem_t *) shmat(shfull, NULL, 0);
pthread_mutex_t *mutex = (pthread_mutex_t *) shmat(shmutex, NULL, 0);
puts("Ho associato i semafori\n");
err = sem_init(empty, 1, SIZE);
assert(err == 0);
err = sem_init(full, 1, 0);
assert(err == 0);
err = pthread_mutex_init(mutex,NULL);
assert(err == 0);
int shIndiceP = shmget(IPC_PRIVATE, sizeof(int), 0600);//creo indice produttore condiviso
if(shIndiceP == -1)puts("Errore nella creazione indice produttore condiviso!\n");
indiceP = (int *) shmat(shIndiceP, NULL, 0);
*indiceP = 0;
puts("Ho creato e associato l'indice del produttore condiviso");
for(int i = 0; i < linee; i++){//creo array di interi del file
fscanf(f, "%d", &numero);
interi[i] = numero;
}
fclose(f);
for(int i = 0; i < N; i++){
pid = fork();printf("FIGLIO: creato processo %d\n",i);
if(pid == -1){
perror("Errore nella fork!\n");
exit(1);
}
if(pid == 0){ printf("FIGLIO: entro nel processo %d\n",i);
while(1){
err = sem_wait(full);
assert(err == 0);printf("Entro nel processo %d\n",i);
err = pthread_mutex_lock(mutex);
assert(err == 0);
int n = buffer[(*indiceP)++ % SIZE];printf("FIGLIO: Ho prelevato il numero %d e sono %d\n",n,i);
if(n == 0){
err = pthread_mutex_unlock(mutex);
assert(err == 0);
err = sem_post(empty);
assert(err == 0);
exit(0);
}
err = pthread_mutex_unlock(mutex);
assert(err == 0);
err = sem_post(empty);
assert(err == 0);
char potenze[25];
snprintf(potenze, 25, "%s.%d", nomeFile, n);
FILE *fpot = fopen(potenze,"w");
if(fpot == NULL)fprintf(stderr,"Errore creazione file\n");
for(int i = 0; i < linee; i++){
fprintf(fpot, "%ld\n", (long)(pow(interi[i],n)));
}
fclose(fpot);
}
}
}
for(int i = 1; i <= M; i++){//procedura produttore (padre)
err = sem_wait(empty);
assert(err == 0);
err = pthread_mutex_lock(mutex);
assert(err == 0);
buffer[indiceC++ % SIZE] = i;printf("PADRE: ho scritto %d sul buffer\n",i);
err = pthread_mutex_unlock(mutex);
assert(err == 0);
err = sem_post(full);
assert(err == 0);
}
for(int i = 0; i < N; i++){
err = sem_wait(empty);//inserisco carattere di fine
assert(err == 0);
err = pthread_mutex_lock(mutex);
assert(err == 0);
buffer[indiceC++ % SIZE] = 0;printf("PADRE: ho scritto %d sul buffer\n",0);
err = pthread_mutex_unlock(mutex);
assert(err == 0);
err = sem_post(full);
assert(err == 0);
}
err = sem_destroy(empty);//pulisco semafori
assert(err == 0);
err = sem_destroy(full);
assert(err == 0);
err = pthread_mutex_destroy(mutex);
assert(err == 0);
shmctl(shmid1, IPC_RMID, NULL);//pulisco memoria condivisa
shmctl(shmid2, IPC_RMID, NULL);
shmctl(shempty, IPC_RMID, NULL);
shmctl(shfull, IPC_RMID, NULL);
shmctl(shmutex, IPC_RMID, NULL);
shmctl(shIndiceP, IPC_RMID, NULL);
return 0;
}