Differences between revisions 2 and 4 (spanning 2 versions)
Revision 2 as of 2009-04-14 07:04:02
Size: 1583
Editor: anonymous
Comment:
Revision 4 as of 2009-05-05 15:42:13
Size: 3053
Editor: lukisi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
Viene usata nelle definizione di funzioni ''microfunc'' per far si che ci sia un solo microthread per l'esecuzione di una certa funzione, che in esso le varie chiamate siano eseguite in sequenza e che, allo stesso tempo, il chiamante di quella funzione non risulti mai bloccato dalla chiamata. Il microthread incaricato di eseguire queste chiamate in sequenza nel programma netsukuku è chiamato ''dispatcher''. Oltre ai metodi {{{send}}} e {{{recv}}}, che richiamano i metodi {{{send}}} e {{{receive}}} dello {{{stackless.channel}}} incapsulato, fornisce i metodi {{{sendq}}} e {{{recvq}}}.
Line 7: Line 7:
Per far questo si estendono le funzionalità fornite dalla classe {{{stackless.channel}}} per la trasmissione/ricezione di messaggi tra tasklet. La particolarità di questi due metodi è che il chiamante del metodo {{{sendq}}} non resta mai bloccato. Vediamo meglio.

Con la normale classe {{{stackless.channel}}} quando una tasklet (termine equivalente a microthread) sta in ascolto con il metodo {{{receive}}} per un messaggio che non è stato ancora inviato, questa tasklet si blocca.
Line 9: Line 11:
Con la normale classe {{{stackless.channel}}} quando una tasklet sta in ascolto per un messaggio che non è stato ancora inviato, questa tasklet non è presa in considerazione dallo schedulatore e quindi non impegna la CPU. Questo va bene anche al programma netsukuku. Quando una tasklet invia un messaggio con il metodo {{{send}}} su un canale dove nessuno sta in ascolto questa tasklet chiamante viene bloccata.
Line 11: Line 13:
Ma quando una tasklet invia un messaggio su un canale dove nessuno sta in ascolto (in netsukuku avviene quando il ''dispatcher'' è ancora impegnato dalla precedente chiamata) questa tasklet chiamante viene bloccata. Questo non va bene al programma netsukuku. Invece, usando la classe Channel e il metodo {{{sendq}}}, tramite l'uso dell'attributo {{{balance}}} del {{{channel}}} si evita che, nel caso sopra descritto, le chiamate vengano accodate alla maniera classica. Invece si memorizzano in una lista che il metodo {{{recvq}}} prenderà in considerazione.

Questo comportamento è molto importante in alcuni punti critici del programma Netsukuku.
Line 13: Line 17:
Tramite l'uso dell'attributo {{{balance}}} del {{{channel}}} si evita che, nel caso sopra descritto, le chiamate vengano accodate alla maniera classica. Invece si memorizzano in una lista che il ''dispatcher'' prenderà in considerazione non appena potrà. Ad esempio viene usata nelle definizione di funzioni ''microfunc'' per far si che ci sia un solo microthread per l'esecuzione di una certa funzione, che in esso le varie chiamate siano eseguite in sequenza e che, allo stesso tempo, il chiamante di quella funzione non risulti mai bloccato dalla chiamata. Il microthread incaricato di eseguire queste chiamate in sequenza nel programma netsukuku è chiamato ''dispatcher''.
<<BR>>
Con il semplice uso di {{{stackless.channell}}}, quando una tasklet richiama una funzione ''microfunc'' in un momento in cui il ''dispatcher'' è ancora impegnato da una precedente chiamata, questa tasklet chiamante risulterebbe bloccata. Questo non va bene al programma netsukuku.
<<BR>>
Tramite l'uso della classe Channel e del metodo {{{sendq}}} le chiamate vengono immediatamente memorizzate nella lista (o coda) del Channel e il ''dispatcher'' le prenderà in considerazione non appena potrà usando il metodo {{{recvq}}}.
Line 15: Line 23:
'''TODO''': spiegare l'uso del costruttore con {{{micro_send=True}}}, cosa comporta e quando viene usato in netsukuku. Un altro metodo fornito dalla classe Channel è {{{bcast_send}}}. Con questo metodo si invia un messaggio a tutte le tasklet in ascolto sul Channel.
<<BR>>
Per definizione, questo metodo non bloccherà mai la tasklet che effettua l'invio. '''''TODO''': Perché si è fatto uso di sendq invece di usare send? Perché quello strano costrutto "for"?''

Un altro modo di usare la classe Channel è quello di istanziarla usando il costruttore con {{{micro_send=True}}}.
<<BR>>
Di nuovo quello che si vuole ottenere è che l'invio di un messaggio non risulti bloccante per il microthread che lo fa. Questa volta però lo si ottiene iniziando un nuovo microthread ad ogni messaggio che si invia sul channel.
<<BR>>
Questo metodo è usato in particolare nel microthread che gestisce la funzione {{{ManageSockets}}} - vedi spiegazione dettagliata nella pagina del [[../ModuloMicrosock|modulo microsock]].

La classe Channel

E' un wrapper della classe stackless.channel.

Oltre ai metodi send e recv, che richiamano i metodi send e receive dello stackless.channel incapsulato, fornisce i metodi sendq e recvq.
La particolarità di questi due metodi è che il chiamante del metodo sendq non resta mai bloccato. Vediamo meglio.

Con la normale classe stackless.channel quando una tasklet (termine equivalente a microthread) sta in ascolto con il metodo receive per un messaggio che non è stato ancora inviato, questa tasklet si blocca.
Quando una tasklet invia un messaggio con il metodo send su un canale dove nessuno sta in ascolto questa tasklet chiamante viene bloccata.
Invece, usando la classe Channel e il metodo sendq, tramite l'uso dell'attributo balance del channel si evita che, nel caso sopra descritto, le chiamate vengano accodate alla maniera classica. Invece si memorizzano in una lista che il metodo recvq prenderà in considerazione.

Questo comportamento è molto importante in alcuni punti critici del programma Netsukuku.
Ad esempio viene usata nelle definizione di funzioni microfunc per far si che ci sia un solo microthread per l'esecuzione di una certa funzione, che in esso le varie chiamate siano eseguite in sequenza e che, allo stesso tempo, il chiamante di quella funzione non risulti mai bloccato dalla chiamata. Il microthread incaricato di eseguire queste chiamate in sequenza nel programma netsukuku è chiamato dispatcher.
Con il semplice uso di stackless.channell, quando una tasklet richiama una funzione microfunc in un momento in cui il dispatcher è ancora impegnato da una precedente chiamata, questa tasklet chiamante risulterebbe bloccata. Questo non va bene al programma netsukuku.
Tramite l'uso della classe Channel e del metodo sendq le chiamate vengono immediatamente memorizzate nella lista (o coda) del Channel e il dispatcher le prenderà in considerazione non appena potrà usando il metodo recvq.

Un altro metodo fornito dalla classe Channel è bcast_send. Con questo metodo si invia un messaggio a tutte le tasklet in ascolto sul Channel.
Per definizione, questo metodo non bloccherà mai la tasklet che effettua l'invio. TODO: Perché si è fatto uso di sendq invece di usare send? Perché quello strano costrutto "for"?

Un altro modo di usare la classe Channel è quello di istanziarla usando il costruttore con micro_send=True.
Di nuovo quello che si vuole ottenere è che l'invio di un messaggio non risulti bloccante per il microthread che lo fa. Questa volta però lo si ottiene iniziando un nuovo microthread ad ogni messaggio che si invia sul channel.
Questo metodo è usato in particolare nel microthread che gestisce la funzione ManageSockets - vedi spiegazione dettagliata nella pagina del modulo microsock.

Netsukuku/ita/ClasseChannel (last edited 2009-05-06 11:19:27 by lukisi)