Newsgroup: it.comp.os.linux.development
Titolo: Aiuto su semafori

Salve gente!
Sto scrivendo un programma con shared memory e semafori.
Non sto pero' riuscendo a fare una cosa: usare i semafori
come interruttori binari(deviatori).
spiego: setto un semaforo (che era a 0) e lo lascio a 1.
quando un altro processo vede che e' a 1, fa "le sue cose" e lo rimette a 0,
l'altro quando vede che e' tornato a 0 riparte e lo rimette a 1...
cosi' via.
tutto questo pero' evitando un loop manuale e utilizzando gli "sleep"
nativi dei semafori.
da quanto ho capito questo non e' possibile. sbaglio?
ciao
tnx
-- 
Dodiesis
:sign under construction:

 nativi dei semafori.
ma non ti serve metterti in sleep. Lo sai che sui semafori sono definite le
due operazioni up e down, delle quali una blocca e l'altra sblocca. Se il
semaforo è sbloccato il primo thread lo blocca traquillamente. Se invece è
bloccato il secondo thread che chiama il bloccaggio finisce in sleep
direttamente. Quando il primo thread rilascia il semaforo automaticamente
il sistema operativo sveglia uno dei thread che dormivano in attesa del
bloccaggio del semaforo.

 bloccaggio del semaforo.
tnx per la risposta... ma o non sono stato chiaro io, o non ho capito quel
che dici.
tu mi suggerisci che dovrei fare in entrambi i programmi un loop infinito
con una semop bloccante per il semaforo; cosicche' i programmi blocchino e
rilascino il semaforo a turno. giusto?
il problema e' che non e' detto che il secondo programma ci sia sempre.
il primo pgm deve scrivere un dato nella shared memory e aspettare che l'altro
lo legga, SENZA piu' scrivere nulla fino ad avvenuta lettura da parte
del secondo.
Io stavo cercando di utilizzare il semaforo a mo di "gestore del turno di
scrittura", e non come bloccaggio della risorsa.
Con quel che mi suggerisci tu, il primo pgm continuerebbe a scrivere a
manetta nella sharedm.
so che i semafori andrebbero utilizzati come "bloccanti per risorse" e non
cosi', ma quel che mi ha fatto pensare e' il complicato meccanismo di
sem_op che ho letto nel man 2 semop :
	If  sem_op  is  a  positive  integer, [...]
	If  sem_op  is  zero,  the  proc[...]
	etc.etc.
ho creduto che ci fosse un trucco/algoritmo per utilizzare i semafori
anche come "gestori di turno"... ma nulla da fare.
Credo di aver trovato una soluzione con le code di messaggi.
sbaglio?
Grazie mille per l'aiuto.
ciao


 sbaglio?
Con i messaggi il programma che scrive deve mandare il messaggio "Ho
scritto", ma quello che legge deve per forza inviare: "Ho letto". Cosi' lo
"scrittore" evita di continuare a scrivere e mandare messaggi che
altrimenti rimarrebbero in nella coda.
Nicola.
-- 
chi va pian va san e va lontan

 altrimenti rimarrebbero in nella coda.
continuando....
io comunque devo usare 2 code: una per il server e una per i client.
vedo infatti che non e' possibile monitorare semplicemente una coda
leggerne i messaggi estrarli per forza.
una volta letto il messaggio e' per forza eliminato.
in pratica: se io mando in coda un messaggio tipo "ho scritto", poi torno a
leggere se qualcun altro ha mandato un "ho letto", non faccio altro che
imbattermi nel mio "ho scritto" e cancellarlo. cosi' in coda non c'e piu'
nulla e nessuno fa piu' niente...
bu
che complicato...
ciao!


 sbaglio?
con quella hai una fifo, però se tenti di scrivere in una pipe che non ha
lettori ti becchi SIGPIPE. 

 nulla e nessuno fa piu' niente...
No, non ti servono 2 code. Nelle code di messaggi quando ricevi devi
controllare il campo long msgtyp:
z = msgrcv(msqid, &msg, msgsz, msgtyp, IPC_NOWAIT | MSG_NOERROR);
if( z == -1 && errno == ENOMSG)  {
         return(0);       //ritorno se non c'e' nessun messaggio
}
Se msgtyp corrisponde alla variabile mtype della struttura inviata: 
struct msgbuf {
      long mtype;     /* message type, must be > 0 */
      char mtext[1];  /* message data */
};
 allora la msgrcv ti tira su il messaggio, altrimenti lo lascia nella coda.
Per il server dovresti mettere in mtype il pid del processo destinatario,
cosi' che il client questo si prenda solo i propri messaggi
(msgtyp=getpid()).
Invece per il client potresti impostare mtype su un numero fisso (1 di
solito visto che solo init ha quel pid) e il server si prende i messaggi
solo con quel msgtyp.
Comunque in rete trovi degli esempi fatti bene ;)



Con i messaggi ti viene piu' semplice.
Ciao.

 (msgtyp=getpid()).
[...]
grazie mille... alla fine ci sono arrivato da solo :)
sono rimasto un po' li a chiedermi a cosa servisse quell'mtype e se
potessi usarlo per i miei scopi... ho provato e ha funzionato :)
/me uomo felice!
ora devo reimpllementare il tutto daccapo, servendomi dei thread e della
loro memoria comune.
Mi serve per sapere qual'e' il modo piu' veloce di scambiarsi grandi
quantita' di dati:thread o IPC.
Poi vi faro' sapere... si sa mai che interessi a qualcuno.
segnalazione: fondamentale e' stata la lettura del gapil, ottimo manuale per
programmazione il linux.
ciao&grazie!


 dato in shm e mette il semaforo in stato "libero"
e' qua il problema: non ci si puo' bloccare sul semaforo in caso sia
"libero". o meglio: se ne potrebbe controllare di continuo lo stato e
aspettare che si "occupi"... ma non e' una souzione accettabile per due
motivi
- si perde l'atomicita': dovrei controllare il semaforo, fare un confronto
e poi bloccare. sono due funzioni distinte. in mezzo alle due funzioni
potrebbe succedere qualcosa (tipo un cambio delllo stato), che non e'
bello.
- si lascia sempre a manetta il processore.
qusto e' almeno quello che ho capito io...
ma posso sempre dire min$%$ate.
ciao!


- si lascia sempre a manetta il processore.
Hai ragione, ci voglio 2 semafori ...
Ciao.

 quantita' di dati:thread o IPC.
...
Se usi shm una volta che l'hai mappata nello spazio di indirizzamento dei
processi non credo ci sia molta differenza rispetto ai pthreads.
Pero' il context switch fra pthreads e' piu' veloce.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! A mathematician is a device for turning coffee into theorems. !>-
                P. Erdos

 Pero' il context switch fra pthreads e' piu' veloce.
alur: posto i risultati...(che nn ci convincono)
primo test:
due prg distinti. uno genera un numero random e ci riempie la shm
rnd = (int)(rand()*(10.0/RAND_MAX));
memset((void *)shm_ptr, rnd, SHM_SIZE);
sblocca il semaforo (precedentemente bloccato) e manda un messaggio una
message queue. poi aspetta.
l'altro, che stava aspettando il messaggio, lokka il semaforo, copia la
shm:
memcpy ((void *)&real_value , shm_ptr, SHM_SIZE ) ;
poi slokka e rimanda un messaggio allo scrittore. loop.
secondo test:
un prg che genera 2 thread: 
uno blocca un mutex, scrive in una variabile comune (stessa procedura
random), manda un segnale (con pthread_cond_broadcast) e si mette in
attesa (con pthread_cond_wait).
l'altro thread (ricevendo il segnale) blocca il mutex, legge la variabile
comune, rimanda un altro segnale e si rimette in attesa.
in entrambi i casi la variabile scambiata e' una 
char text[102400] ;
e viene scritta (e letta) 1024000 volte.
ecco i tempi:
$ time ./ipc
real	0m38.229s
user	0m18.570s
sys	0m3.060s
$ time ./thread 
real	0m56.073s
user	0m13.540s
sys	0m6.810s
morale: i thread sono piu' lenti...
ma nn era il contrario?
ciao!


ma nn era il contrario?
Non interpreti bene l'output di time, non devi guardare il real, ma la
somma tra user e sys, che, come puoi vedere, e' minore nel caso dei
thread. Il real tiene conto anche delle attese passive.
Ciao.

 ma nn era il contrario?
Infatti in generale no. Pensa a come funziona la VM dei processi e dei
thread. BTW al posto di condwait potresti usare dei semafori, no?
NP: Thunder - She's So Fine
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! The Moment Is Now In All History, The Time Has Arrived And This Is The
  		One Place To Be. !>- Savatage - This Is The Time

 wrote:
 >ecco i tempi:
 >
 >$ time ./ipc
 >real	0m38.229s
 >user	0m18.570s
 >sys	0m3.060s
 >
 >$ time ./thread
 >real	0m56.073s
 >user	0m13.540s
 >sys	0m6.810s
 >
 >
 >morale: i thread sono piu' lenti...
 >ma nn era il contrario?
Non interpreti bene l'output di time, non devi guardare il real, ma la 
