Newsgroup: it.comp.os.linux.development
Titolo: Message queues..

Salve a tutti,
premetto che non sono uno sviluppatore... mi
occupo di tutt'altra cosa, ma sto facendo un piccola
applicazione su Linux e credo (spero) che voi mi
possiate chiarire questo dubbio:
Scenario
processo A che scrive su una message queue
processi  X, Y, Z che leggono da questa message
queue...
I processi X, Y, Z fanno tutti esattamente la stessa
cosa (sono lo stesso eseguibile): leggono la coda (1)
elaborano il messaggio e sputano il risultato su
una altra coda (2) condivisa.
Ora mi sorge il dubbio sulla concorrenza dei processi:
mentre non dovrei avere problemi se A e X accedono
contemporaneamente alla coda (uno scrive l'altro legge),
posso avere problemi per i processi X Y e Z ?
Ovviamente sia in scrittura che in lettura...
Secondo voi mi tocca mettere un semaforo per l'utilizzo
della coda o Linux risolve l'accesso contemporaneo
alla risorsa di per se?
Grassie
/G

 alla risorsa di per se?
La prima che hai detto

|
| Suppongo che per coda tu intenda pipe....
Intendo Message Queue... la struttura messa a
disposizione dagli IPC
Insomma quella che viene usata utilizzando le
syscall: msgget, msgrcv... etc etc
| > Secondo voi mi tocca mettere un semaforo per l'utilizzo
| > della coda o Linux risolve l'accesso contemporaneo
| > alla risorsa di per se?
|
| La prima che hai detto
oh kappa... procederò
/G

someone wrote:

L'accesso alle MQ e` atomico. Se leggi un messaggio e la lettura ha 
successo questo viene rimosso dalla coda. Se lo scrivi ci viene messo. Non 
sono possibili interventi di altri processi nel mezzo.
 
Il punto pero` e` come vuoi usare le MQ e cosa vuoi fare di preciso. 
Chiaramente se piu` processi leggono lo stesso tipo di messaggio solo uno 
riuscira` a leggerlo, e non potrai, senza meccanismi di sincronizzazione 
esterna, prevedere quale. Per cui o differenzi i messaggi a seconda del 
tipo o prevedi meccanismi di sincronizzazione.
Ciao
-- 
As.| Simone Piccardi - KeyID:2A972F9D - 
JabberID:sim...@jabber.linux.it
 
So.| 
http://firenze.linux.it/~piccardi
  -  
http://www.softwarelibero.it
 
Li.| Prima ti ignorano, poi ti deridono, poi ti combattono.  Poi vinci. 
                                                           M. K. Ghandi

| Il punto pero` e` come vuoi usare le MQ e cosa vuoi fare di preciso.
|
| Chiaramente se piu` processi leggono lo stesso tipo di messaggio solo uno
| riuscira` a leggerlo, e non potrai, senza meccanismi di sincronizzazione
| esterna, prevedere quale
Non mi interessa quale processo leggerà cosa... la cosa che mi
preme è che un processo può leggere il msg x senza che un altro
processo contemporaneamente legga il medesimo msg...
Se tu mi dici che "uno solo riuscirà a leggerlo" ne deduco che
il SO pone un qualche tipo di blocco sulla risorsa immediatamente
prima che il messaggio sia letto e sblocca la risorsa subito dopo
che il messaggio è stato cancellato dalla coda...
mi do anche un'occhiatina al source code del kernel...
//G

 oh kappa... procederò
Mi riferivo con le pipe

disposizione dagli IPC
La cosa migliore che puoi fare con le message queues è non usarle. Tutto
quello che stai facendo ora lo puoi fare con un lock file + un file in
cui scrivere l'input ai processi consumatori. 
-- 
"L'Italia è un interessante esempio di avanguardia teatrale" (Gore Vidal)
Per rispondermi, ricordati di togliere il nome del poeta.

| La cosa migliore che puoi fare con le message queues è non usarle.
controindicazioni specifiche? o generali?
 Tutto
| quello che stai facendo ora lo puoi fare con un lock file + un file in
| cui scrivere l'input ai processi consumatori.
Il sistema deve essere in grado di processare 200 msg secondo...
i/o su file è la prima cosa che ho cancellato
/G

 i/o su file è la prima cosa che ho cancellato
Suggerirei di prendere in seria considerazione l'impiego di pipe, o di
named pipe (FIFO), se i processi non sono imparentati.
Max

i/o su file è la prima cosa che ho cancellato
Ti ho suggerito di fare come fa Apache in mod_rewrite. (hint: il
file/la pipe sarebbe in memoria, visto il caching fatto da VFS).


| Potrebbero non essere portabili, non hanno nessuna particolare
| efficienza, Stevens raccomanda di non usarle.
ogghey... ne tengo conto...
| > Tutto
| >| quello che stai facendo ora lo puoi fare con un lock file + un file in
| >| cui scrivere l'input ai processi consumatori.
| >
| >Il sistema deve essere in grado di processare 200 msg secondo...
| >i/o su file è la prima cosa che ho cancellato
|
| Ti ho suggerito di fare come fa Apache in mod_rewrite. (hint: il
| file/la pipe sarebbe in memoria, visto il caching fatto da VFS).
mi vedrò il source code...
ma da quello che ho capito leggendo la documentazione delle
NP... il processo in scrittuta aspetta che un processo in lettura
scodi dalla NP...
Questo è proprio quello che non voglio... con le MQ in pratica
costruisco una specie di buffer: i msg in entrata sono 200/sec
i miei processi scodano a 50/sec... single queue multiple server
(alla Tuxedo se avete un po di dimestichezza con gli AS)
metto su 5 processi e non se ne parla più...
Ora se c'è la possibilità di utilizzare la NP come un buffer...
la prenderò in considerazione...
/G

 metto su 5 processi e non se ne parla più...
Ecco, ora è chiaro il problema; quello che mi viene in mente ( come 
soluzione ) è la seguente ( con 3 client, ma può essere generalizzata ):
                                                --PP--> client 1
                                             /
processo server <--PP-->  scheduler <--PP--> client 2
                                             \
                                                --PP--> client 3
<--PP-->  è una pipe ( o una socket se preferisci )
Il server ed il client sono processi semplici: il server non fa altro che 
mettere roba sulla coda ( in modalità bloccante ), i client non fanno altro
che leggere dalla coda ( sempre in modalità bloccante ).
Il vero processo "complicato" è lo scheduler che funziona più o meno cosi:
- attende un eveneto dalle pipe ( che sono il lettura (server ) o in 
scrittura(client) ) con select/poll
- se ci sono dati in arrivo legge in modalità NON bloccante dalla pipe verso 
il server, e li mette in un buffer.
- se ci sono richieste di lettura dai client, ed il buffer non è vuoto, 
scrive ( in modalità NON bloccante ) verso i client.
Credo che sia il sistema più portabile. L'unica cosa delicata è la scrittura 
dello scheduler, il cui compito principale è quello di fornire un buffer 
ampio ( cosa che le pipe non forniscono ); inoltre deve gestire la 
nascita/morte dei processi client/server..

|                                                 --PP--> client 1
|                                              /
| processo server <--PP-->  scheduler <--PP--> client 2
|                                              \
|                                                 --PP--> client 3
|
|
| <--PP-->  è una pipe ( o una socket se preferisci )
questa è la stessa architettura che avevo pensato prima di avere
un buffer unico in entrata con le MQ... ma al posto delle PP
avevo pensato di mettere delle altre MQ.
Gira, perchè gira... ma come hai detto te il processo "critico"
è lo scheduler.. sommariamente avevo pensato che per avere un
bilanciamento serio delle code in uscita, avrei dovuto prendere
in considerazione non un semplice 'round robin' sulle code, ma
un algoritmo più complesso che tenga conto del carico di
lavoro effettivo di ogni singolo processo (per avere uno straccio
di load balancing).
Altra cosa a complicare le cose è il buffer interno dello scheduler
come lo implemento? shared memory?...
| Credo che sia il sistema più portabile. L'unica cosa delicata è la
scrittura
Ho letto in giro appunto della portabilità dei MQ etc etc...
Però mi domando anche application server come Tuxedo o RDBMS
come Oracle fanno uso massiccio e intensivo di MQ Sem e SM...
Bah... vabbè
| ampio ( cosa che le pipe non forniscono ); inoltre deve gestire la
| nascita/morte dei processi client/server..
Questo IMHO non lo dovrebbe fare lo scheduler, secondo la mia
architettura esiste un processo esterno che si preoccupa di gestire
i vari heartbeat dei processi, tirarli giù e tirarli su quando necessario
Perchè se crepa lo scheduler chi lo tira su?
/G

 come Oracle fanno uso massiccio e intensivo di MQ Sem e SM...
Oracle 8 sotto Linux/Solaris fa uso di SM e Sem, ma non di MQ.
Max

 Perchè se crepa lo scheduler chi lo tira su?
E' lo scheduler che intreccia rapporti con tutti i processi, e poi è 
semplice nello scheduler creare pipe e lanciare processi; se lo deve fare 
un processo super-partes è più complicato creare una pipe. Mi spiego con un 
esempio:
comunicazione scheduler <--PP--> processo server ( l'output del server deve 
andare nell'inoput dello  scheduler )
        int     pp[2];
        /* generazione server */
        pipe( pp );
        if( pid=fork( ) ){
                /* father */
                close( pp[1] );
                /* il padre(scheduler) legge da pp[0] */
        }else{
                /* child */
                close( pp[0] );
                dup( pp[1],1 );
                /* il figlio(server) scrive su pp[1] */
                exec( /* child */ )
        }
        [...]
        /* generazione client */
        pipe( pp );
        if( pid=fork( ) ){
                /* father */
                close( pp[0 );
                /* il padre(scheduler) scrive su pp[1] */
        }else{
                /* child */
                close( pp[1 );
                dup( pp[0]0);
                /* il figlio(client) legge da pp[0] */
                exec( /* child */ )
        }
Così i figli server e client  si ritroveranno a lavorare su  rispettivamente 
standard-out e stdndard-in...