Evitare la ricorsione durante la lettura / scrittura di una porta in modo sincrono?


108

Tutte le operazioni portuali in Rebol 3 sono asincrone. L'unico modo che riesco a trovare per fare una comunicazione sincrona è chiamare wait.

Ma il problema con la chiamata di wait in questo caso è che controllerà gli eventi per tutte le porte aperte (anche se non sono nel blocco di porte passato ad wait). Quindi chiamano i gestori di eventi che rispondono, ma è possibile eseguire una lettura / scrittura in uno di questi gestori di eventi. Ciò potrebbe comportare chiamate ricorsive a "wait".

Come posso aggirare questo problema?


8
In realtà, non penso che ci sia una soluzione a questo nell'attuale implementazione R3, quindi sono andato avanti per aggiungere un raffinamento "/ only" ad "wait", con il quale aspetterà solo sulle porte fornite per "aspettare" e quindi evitare le chiamate ricorsive. Vedi la mia richiesta di pull su: github.com/rebol/rebol/pull/177
Shixin Zeng

1
Per curiosità, perché hai bisogno che sia sincrono?
toadzky

1
Ci sono molte situazioni in cui la codifica con la porta sincrona è molto più semplice: supponi di voler inviare un'e-mail con un clic su un pulsante e segnalare se ha successo o meno. È molto più facile aspettare che sia finito prima di fare qualsiasi altra cosa.
Shixin Zeng

1
devi assolutamente usare Rebol?
Rivenfall

1
Sì. Questa è in realtà più una domanda su Rebol 3 che sulla comunicazione sincrona in generale.
Shixin Zeng

Risposte:


1

Perché non crei una sorta di funzione "Buffer" per ricevere tutti i messaggi da voci asincrone ed elaborarli come FIFO (first-in, first-out)?

In questo modo puoi mantenere le caratteristiche Assync delle tue porte ed elaborarle in modalità di sincronizzazione.


0

nei casi in cui ci sono solo eventi asincroni e abbiamo bisogno di una risposta sincrona, avvia un timer o dormi per timeout, se il gestore o l'obiettivo richiesto viene raggiunto, dì vero, altrimenti falso e assicurati che l'evento venga cancellato / ripristinato per il lo stesso se critico.


0

Penso che ci siano 2 problemi di progettazione (forse intrinseci agli strumenti / soluzioni a portata di mano).

  1. Waitsta facendo troppo - it will check events for all open ports. In un ambiente sano, l'attesa dovrebbe essere implementata solo dove è necessaria: per dispositivo, per porta, per socket ... La creazione di interdipendenze non necessarie tra le risorse condivise non può finire bene, soprattutto sapendo che le risorse condivise (anche senza interdipendenze) può creare molti problemi.

  2. I gestori di eventi potrebbero fare troppo. Un gestore di eventi dovrebbe essere il più breve possibile e dovrebbe gestire solo l'evento. Se fa di più, il gestore sta facendo troppo, specialmente se coinvolge altre risorse condivise. In molte situazioni, il gestore salva semplicemente i dati che altrimenti andrebbero persi; e un lavoro asincrono farà le cose più complesse.


-1

Puoi semplicemente usare un lucchetto. Cummunication1 può impostare uno stato di blocco globale, ad esempio con una variabile (assicurarsi che sia thread-safe). locked = true. Quindi Communication2 può attendere fino a quando non viene sbloccato.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()

1
Questa è in realtà più una domanda su Rebol 3 che sulla comunicazione sincrona in generale.
Shixin Zeng
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.