codice:
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#define N 1
// definisco una struttura messaggio che mi servirà per la lettura/scrittura delle stringhe
struct msg {
char *mex;
};
// definisco struttura port; area array circolare con relativi parametri come vettore di N elementi di tipo msg, mutex e condition variables (regione critica, operazioni atomiche)
struct port {
struct msg messages[N];
pthread_mutex_t m;
pthread_cond_t empty;
pthread_cond_t full;
int count;
int head;
int tail;
};
// inizializzo struttura port
struct port *port_init(void) {
struct port *p;
p = malloc(sizeof(struct port));
if (p == NULL) {
return NULL;
}
p->head = 0;
p->tail = 0;
p->count = 0;
pthread_mutex_init(&p->m, NULL);
pthread_cond_init(&p->empty, NULL);
pthread_cond_init(&p->full, NULL);
return p;
}
// definisco puntatore struttura port (variabili visibili da tutto il processo (quindi condivise tra i singoli thread)
struct port *p, *q;
int passo=1;
void msg_send(struct port *p, struct msg *m) {
// accedo in mutua esclusione
pthread_mutex_lock(&p->m);
while (p->count == N) {
// controlla (ciclicamente) la condition variable. se la coda è piena sblocca il mutex (per gli altri processi) e si blocca; altrimenti blocca il mutex e scrive
pthread_cond_wait(&p->full, &p->m);
}
// scrivo il messaggio nell'area condivisa
memcpy(&p->messages[p->tail], m, sizeof(struct msg));
// incremento la coda e il count
p->tail = (p->tail + 1) % N;
p->count = p->count + 1;
// dormo per un pò (per far notare l'invio)
usleep(500000);
// sblocco condition variable e il mutex
pthread_cond_signal(&p->empty);
pthread_mutex_unlock(&p->m);
}
void msg_receive(struct port *p, struct msg *m) {
// accedo in mutua esclusione
pthread_mutex_lock(&p->m);
while (p->count == 0) {
// controlla (ciclicamente) la condition variable. se la coda è vuota sblocca il mutex (per gli altri processi) e si blocca; altrimenti blocca il mutex e legge
pthread_cond_wait(&p->empty, &p->m);
}
// leggo il messaggio nell'area condivisa
memcpy(m, &p->messages[p->head], sizeof(struct msg));
// decremento testa e count
p->head = (p->head + 1) % N;
p->count = p->count - 1;
// dormo per un pò (per far notare la ricezione)
usleep(500000);
// sblocco condition variable e il mutex
pthread_cond_signal(&p->full);
pthread_mutex_unlock(&p->m);
}
void *th1_create(void *v) {
// definisco la mia struttura messaggio, stringa da generare e attributi per questo thread
struct msg m;
char str_random[10];
int j,i, cs=0;
srand(time(NULL));
// genero e invio 10 stringhe
for (i=0; i<10; i++) {
for (j=0; j<10; j++) {
str_random[j]=rand() % 93 + 33;
}
m.mex=str_random;
msg_send(p, &m);
cs++;
printf("%d - T1 - Stringa n.%d inviata : %s\n", passo++, cs, m.mex);
}
// invio messaggio chiusura da parte del thread 1
m.mex="end_transmission_t1";
msg_send(p, &m);
return NULL;
}
void *th2_elabore(void *v) {
// definisco la mia struttura messaggio, stringa da generare e attributi per questo thread
struct msg m;
char str_conv[20];
int i=1, cs=0;
// ricevo, elaboro e invio le 10 stringhe
while(i==1) {
msg_receive(p, &m);
if(m.mex=="end_transmission_t1") {
i=2;
} else {
int j, count_pwd=0;
for (j=0; j<10; j++) {
count_pwd=count_pwd+(int)m.mex[j];
}
sprintf(str_conv, "%s%d", "", count_pwd);
cs++;
printf("%d - T2 - Stringa n.%d ricevuta : %s - Codifica corrispondente : %d\n", passo++, cs, m.mex, count_pwd);
m.mex=str_conv;
msg_send(q, &m);
}
}
// invio messaggio chiusura da parte del thread 2
m.mex="end_transmission_t2";
msg_send(q, &m);
return NULL;
}
void *th3_send(void *v) {
// definisco la mia struttura messaggio, stringa da generare e attributi per questo thread
struct msg m;
int i=1, cs=0;
// ricevo e invio al device driver le mie 10 stringhe
while(i==1) {
msg_receive(q, &m);
if(m.mex=="end_transmission_t2") {
i=2;
} else {
int j, count_pwd=0;
for (j=0; j<10; j++) {
count_pwd=count_pwd+(int)m.mex[j];
}
cs++;
printf("%d - T3 - Stringa n.%d elaborata ricevuta : %s\n", passo++, cs, m.mex);
}
}
return NULL;
}
int main(int argc, char *argv[]) {
int err;
pthread_t th1, th2, th3;
p = port_init();
q = port_init();
err = pthread_create(&th1, NULL, th1_create, NULL);
if (err) {
perror("PThread Create");
}
err = pthread_create(&th2, NULL, th2_elabore, NULL);
if (err) {
perror("PThread Create");
}
err = pthread_create(&th3, NULL, th3_send, NULL);
if (err) {
perror("PThread Create");
}
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
printf("\nStrings sent successfully...\n");
return 0;
}
il problema stà nel fatto che T1 invia, T2 riceve ma riceve la stringa che T1 (in teoria) dovrebbe inviare al secondo passo... non capisco se è un problema di casting o che cosa...