Ecco il mio codice
Codice: Seleziona tutto
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <ctype.h>
#define DIM 1024
#define MUTEX 0 // sem mutex
#define FULL 1 // sem full
#define EMPTY 2 // sem empty
#define MUTEX2 3 // sem mutex
#define FULL2 4 // sem full
#define EMPTY2 5 // sem empty
#define TYPE_P 2
#define TYPE_F 3
#define TYPE_FN 4
typedef struct
{
char text[DIM];
long type;
} msg;
int WAIT(int sem_id, int sem_num)
{
struct sembuf ops[1] = {{sem_num, -1, 0}};
return semop(sem_id, ops, 1);
}
int SIGNAL(int sem_id, int sem_num)
{
struct sembuf ops[1] = {{sem_num, +1, 0}};
return semop(sem_id, ops, 1);
}
void father(int shm_id, int sem_id, char *filename, msg *p)
{
FILE *r_stream;
char tmp[DIM];
if ((r_stream = fopen(filename, "r")) == NULL)
{
perror("fopen");
exit(1);
}
while (fgets(tmp, DIM, r_stream) != NULL)
{
printf("Father -> %s", tmp);
WAIT(sem_id, EMPTY);
WAIT(sem_id, MUTEX);
strcpy(p->text, tmp);
p->type = TYPE_F;
SIGNAL(sem_id, MUTEX);
SIGNAL(sem_id, FULL);
}
WAIT(sem_id, EMPTY);
WAIT(sem_id, MUTEX);
strcpy(p->text, "EOF");
p->type = TYPE_F;
SIGNAL(sem_id, MUTEX);
SIGNAL(sem_id, FULL);
fclose(r_stream);
printf("father final\n");
int done = 0;
while (done == 0)
{
WAIT(sem_id, FULL2);
WAIT(sem_id, MUTEX2);
strcpy(tmp, p->text);
SIGNAL(sem_id, MUTEX2);
SIGNAL(sem_id, EMPTY2);
printf("Father final: %s",tmp);
if (strcmp(tmp, "EOF") == 0)
done = 1;
}
}
void filter(int shm_id, int sem_id, int child, msg *p, char *word)
{
int done = 0;
while (done == 0)
{
char text[DIM];
WAIT(sem_id, FULL);
WAIT(sem_id, MUTEX);
strcpy(text, p->text);
SIGNAL(sem_id, MUTEX);
SIGNAL(sem_id, EMPTY);
if (strcmp(text, "EOF") != 0)
{
printf("\tFilter-> %s", text);
for (int i = 0; i < strlen(text); i++)
{
text[i] = toupper(text[i]);
}
WAIT(sem_id, EMPTY2);
WAIT(sem_id, MUTEX2);
strcpy(p->text, text);
SIGNAL(sem_id, MUTEX2);
SIGNAL(sem_id, FULL2);
}
else
{
SIGNAL(sem_id, MUTEX2);
SIGNAL(sem_id, FULL2);
strcpy(p->text, "EOF");
SIGNAL(sem_id, MUTEX2);
SIGNAL(sem_id, FULL2);
done = 1;
}
}
exit(0);
}
int main(int argc, char *argv[])
{
/* code */
int shm_id, sem_id, shm_id2;
msg *p, *p2;
if (argc == 1 || argc == 2)
{
fprintf(stderr, "uso: %s file.txt filter-1...filte-n \n", argv[0]);
exit(1);
}
// creo area di memoria condivisa
if ((shm_id = shmget(IPC_PRIVATE, sizeof(msg), IPC_CREAT | 0600)) == -1)
{
perror("shmget");
exit(1);
}
// attacco area di memoria
if ((p = (msg *)shmat(shm_id, NULL, 0)) == (msg *)-1)
{
perror("shmat");
exit(1);
}
// creo i semafori
if ((sem_id = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)) == -1)
{
perror("semget");
exit(1);
}
// inizializzo semafori
semctl(sem_id, MUTEX, SETVAL, 1);
semctl(sem_id, EMPTY, SETVAL, 1);
semctl(sem_id, FULL, SETVAL, 0);
semctl(sem_id, MUTEX2, SETVAL, 1);
semctl(sem_id, EMPTY2, SETVAL, 1);
semctl(sem_id, FULL2, SETVAL, 0);
int child = argc - 2;
char *filename = argv[1];
char *word = argv[2];
if (fork() == 0)
{
filter(shm_id, sem_id, child, p, word);
}
else
{
father(shm_id, sem_id, filename, p);
// distruggo area di memoria condivisa
wait(NULL);
shmctl(shm_id, IPC_RMID, NULL);
// rimuovo i semafoti
semctl(sem_id, FULL, IPC_RMID, 0);
semctl(sem_id, EMPTY, IPC_RMID, 0);
semctl(sem_id, MUTEX, IPC_RMID, 0);
semctl(sem_id, FULL2, IPC_RMID, 0);
semctl(sem_id, EMPTY2, IPC_RMID, 0);
semctl(sem_id, MUTEX2, IPC_RMID, 0);
exit(0);
}
return 0;
}
ecco l'output:
Codice: Seleziona tutto
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Father final: CHé SCHIAVA DI ROMAIDDIO LA CREò.
Qualcuno potrebbe dirmi dove sbaglio ?