Size: 1588
Comment:
|
Size: 2629
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 12: | Line 12: |
@microfunc(is_micro=True) # possibili args sono is_micro=false e is_atomic=falsei | @microfunc(is_micro=True) # possibili args sono is_micro=False e is_atomic=False |
Line 21: | Line 21: |
Se si usa il modo default (primo) tutte le chiamate alla funzione vengono accodate in un channel (vedi la classe {{{Channel}}} con {{{prefer_sender = True}}}) e viene avviato in un microthread un dispatcher che le esegue in sequenza ognuna in un microthread. | Se si usa la modalità default (la prima) al momento della '''definizione''' della funzione viene avviato in un microthread un dispatcher per quella funzione che sta in ascolto su un channel (vedi la [[../ClasseChannel|classe Channel]] con {{{prefer_sender = True}}} e {{{micro_send = False}}}). <<BR>> Al momento della '''chiamata''' della funzione il dispatcher riceve tramite il channel la chiamata e lo scheduler viene informato che il dispatcher è in attesa di eseguire del codice. Il dispatcher esegue le chiamate una alla volta, senza avviare altri microthreads. <<BR>> In realtà bisogna aggiungere che al posto di un channel è usato un oggetto {{{Channel}}} e il passaggio dei dati (cioè gli argomenti della chiamata) avviene con i metodi {{{sendq}}} e {{{recvq}}} (vedi la [[../ClasseChannel|classe Channel]]). Questo significa che se il dispatcher non è pronto a ricevere al momento della chiamata della funzione, il chiamante accoda i dati in una sequence e questo evita che si blocchi il chiamante. <<BR>> Questo meccanismo fa si che ci sia un solo microthread per l'esecuzione di una certa funzione, e che in esso le varie chiamate siano eseguite in sequenza. Ma allo stesso tempo si ottiene che il chiamante di quella funzione non risulti mai bloccato dalla chiamata. |
Line 23: | Line 29: |
Questo significa che quando viene chiamata quella funzione in realtà viene creata una stackless.tasklet cioè un microthread in cui eseguirla. | Se si usa la modalità {{{is_micro}}} si ottiene una funzione che, quando chiamata, viene eseguita in un nuovo microthread. <<BR>> In questo caso ogni chiamata produce un microthread e quindi, naturalmente, il chiamante non risulta mai bloccato dalla chiamata. Diversamente dalla prima modalità si ha che le varie chiamate possono venire eseguite in parallelo. |
Line 25: | Line 33: |
If is_micro != True and is_micro != True (default), each call will be queued. | Se si usa la modalità {{{is_atomic}}} si ottiene una funzione che, quando chiamata, viene eseguita in un microthread che non sarà mai interrotto fino alla sua terminazione. |
Line 27: | Line 35: |
A dispatcher microthread will automatically pop and execute each call. <<BR>> If is_micro == True, each call of the function will be executed in a new microthread. <<BR>> If is_atomic == True, each call will be executed inside a new atomic microthread. WARNING: this means that the microthread won't be interrupted by the stackless scheduler until it has finished running. |
Per ora la modalità {{{is_atomic}}} non è stata mai usata nel codice. |
Il modulo micro
Ha una funzione per richiamare altre funzioni come microthread (micro e microatomic), una classe per la creazione di canali (Channel) e un decorator (microfunc) per definire una funzione che sarà sempre eseguita in microthreads.
Una funzione può essere dichiarata in uno di questi modi:
@microfunc() def funzione_da_eseguire(param1, param2): print param1, param2 @microfunc(is_micro=True) # possibili args sono is_micro=False e is_atomic=False def funzione_da_eseguire(param1, param2): print param1, param2 @microfunc(is_atomic=True) def funzione_da_eseguire(param1, param2): print param1, param2
Se si usa la modalità default (la prima) al momento della definizione della funzione viene avviato in un microthread un dispatcher per quella funzione che sta in ascolto su un channel (vedi la classe Channel con prefer_sender = True e micro_send = False).
Al momento della chiamata della funzione il dispatcher riceve tramite il channel la chiamata e lo scheduler viene informato che il dispatcher è in attesa di eseguire del codice. Il dispatcher esegue le chiamate una alla volta, senza avviare altri microthreads.
In realtà bisogna aggiungere che al posto di un channel è usato un oggetto Channel e il passaggio dei dati (cioè gli argomenti della chiamata) avviene con i metodi sendq e recvq (vedi la classe Channel). Questo significa che se il dispatcher non è pronto a ricevere al momento della chiamata della funzione, il chiamante accoda i dati in una sequence e questo evita che si blocchi il chiamante.
Questo meccanismo fa si che ci sia un solo microthread per l'esecuzione di una certa funzione, e che in esso le varie chiamate siano eseguite in sequenza. Ma allo stesso tempo si ottiene che il chiamante di quella funzione non risulti mai bloccato dalla chiamata.
Se si usa la modalità is_micro si ottiene una funzione che, quando chiamata, viene eseguita in un nuovo microthread.
In questo caso ogni chiamata produce un microthread e quindi, naturalmente, il chiamante non risulta mai bloccato dalla chiamata. Diversamente dalla prima modalità si ha che le varie chiamate possono venire eseguite in parallelo.
Se si usa la modalità is_atomic si ottiene una funzione che, quando chiamata, viene eseguita in un microthread che non sarà mai interrotto fino alla sua terminazione.
Per ora la modalità is_atomic non è stata mai usata nel codice.