PDA

Visualizza la versione completa : [C] Semafori, chi deve eliminarli?


Smoke666
13-12-2012, 16:10
Ciao a tutti, ho un piccolo dilemma che non riesco a risolvere. Ho un server e un client che comunicano tramite socket, per ogni client il server avvia un thread che si incarica di gestire la richiesta. I clienti si sincronizzano tramite un semaforo tra di loro (accesso alla risorsa comune "socket"), e con i thread attraverso un altro. Il server "ignora" l'esistenza di questi semafori, poichè io li creo e li utilizzo nel codice dei thread in questo modo:



char SEM_NAME[] = "nome semaforo";

void *thr_fun(void *par){
sem_t *sem;
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
.......//faccio quello che devo e risveglio il ricevente.
sem_post(sem);
sem_close(sem);
//terminazione thread.
}


I client, invece, ne utilizzano 2 come già detto, uno è quello che utilizzano i thread, chiamato "nome semaforo", e un altro che utilizzano per sincronizzare la scrittura sulla socket:



char SEM_NAME[] = "nome semaforo";
char SEM_CLI[] = "client semaforo";

void client(){
sem_t *sem, *semcli;
sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
semcli = sem_open(SEM_CLI, O_CREAT, 0644, 1);

sem_wait(sem_cli);
//scrittura su socket
sem_post(sem_cli);
//attesa risposta
sem_wait(sem);
//terminazione;
}


La sequenza sopra descritta sembra funzionare, facendo una prova sommaria tutti i clienti riescono a comunicare con i server. Ma ora sorge il mio dubbio: chi dovrebbe essere incaricato di eliminare i semafori tramite sem_unlink() ? Questi andranno eliminati alla fine dell'esecuzione del programma, quindi quando non ci saranno più clienti, e questo lo può conoscere solo il server. Se però io inizializzo i semafori nel server, questi non vengono gestiti correttamente e le comunicazioni non avvengono regolarmente. Sicuramente sbaglio l'approccio, per questo chiedo aiuto a voi: come posso eliminare i semafori mantenendo questa struttura, o in alternativa, come devo modificare la stessa per rendere i semafori "visibili" al server e funzionanti al tempo stesso? Grazie mille!

c0der
13-12-2012, 16:23
Originariamente inviato da Smoke666
I clienti si sincronizzano tramite un semaforo tra di loro

Scusa, lo dico solo come battuta ma tu sei quello delle cose "strane" :) Perché i client si devono sincronizzare tra di loro? non l'ho mai vista una cosa del genere... L'avrai fatto per qualche ragione, vorrei solo capire meglio. I client di solito sono sempre slegati tra loro, qualunque sincronizzazione avviene solo sul server.

Smoke666
13-12-2012, 16:34
Ahahah hai proprio ragione, le "cose strane" mi caratterizzano! :D :D

Dunque, ho una socket che deve essere utilizzata in maniera concorrente da più processi. Se fossi nell'ambito dello stesso processo utilizzerei la mutua esclusione per garantire il corretto utilizzo della socket, essendo però nella situazione di dover far accedere non più di uno scrittore per volta, e i processi non sono "imparentati", devo usare dei semafori per indicare se la risorsa è disponibile o meno. Giusto? :D

Inizialmente non gestivo questo caso nel mio codice, ma mi è stato fatto notare che aumentando il numero di clienti, alcune connessioni andavano "perdute", producendo così risultati non corretti..

c0der
13-12-2012, 16:37
Originariamente inviato da Smoke666
Dunque, ho una socket che deve essere utilizzata in maniera concorrente da più processi.

È qui che non capisco il motivo... perché ogni client non può avere il suo socket?

Smoke666
13-12-2012, 16:42
Premetto che sono in ambiente locale, quindi server e client girano sulla stessa macchina. Il server è solo uno e mette a disposizione una sola socket alla quale tutti i clienti devono connettersi...Come posso utilizzarne diverse? :confused:

c0der
13-12-2012, 16:47
Socket però è generico... che socket intendevi: tcp, unix, ... ? Io ovviamente se dici socket io penso al tcp. P.S. socket è maschile no? Perché la socket?

Smoke666
13-12-2012, 16:50
Hai ragione non l'ho specificato, sono socket unix.

Non saprei, il mio prof ha sempre detto "la socket" e quindi mi sono convinto che fosse femminile :D

c0der
13-12-2012, 17:02
O ricordo male io o gli unix socket si usano come i socket tcp:
http://www.linuxhowtos.org/C_C++/socket.htm (sezione Sockets in the Unix Domain)
Il server fa accept e ogni volta che si connette un client gli viene ritornato un file descriptor diverso.
Ogni client quindi fa la "sua" connessione al server e non ha da condividere nulla.

Smoke666
13-12-2012, 17:18
Ti ho stampato la seguenza di accept del server e di connect dei client, guarda tu stesso:



Client: connessione 4
Server -accept : 5
Client: connessione 4
Client: connessione 4
Server -accept : 6
Client: connessione 4
Server -accept : 7
Server -accept : 8
Client: connessione 4
Server -accept : 9
Server -accept : 13
Client: connessione 4
Client: connessione 5
Server -accept : 5
Client: connessione 5
Client: connessione 5
Server -accept : 6
Client: connessione 5
Client: connessione 5
Server -accept : 7
Client: connessione 6
Server -accept : 5
Server -accept : 8
Server -accept : 9
Client: connessione 6
Server -accept : 6
Client: connessione 6
Client: connessione 6
Client: connessione 6
Server -accept : 7
Server -accept : 8
Server -accept : 9
Client: connessione 5
Server -accept : 10
Server -accept : 11
Client: connessione 4
Client: connessione 5
Server -accept : 11
Client: connessione 6
Client: connessione 6
Server -accept : 10
Server -accept : 11



Questi sono 7 clienti che si connettono a 3 server, come puoi vedere 4, 5, 6 sono ciò che connect ritorna, e ritona lo stesso valore per tutti i clienti. Invece il server ha come ritorno da accept un range di valori più ampio, ma anche qui si ripetono...E' sopratutto per questo che utilizzo i semafori...

Se poi ti può tornare utile ti posso mostrare anche la sequenza che non utilizza i semafori per la scrittura, vedrai che la maggior parte delle comunicazioni non avviene...

c0der
13-12-2012, 17:44
A parte che non capisco quella stampa, rimani un gran confusionario :) Cosa sono i 3 server adesso?

Loading