Casi di utilizzo e modelli di utilizzo dei futures vs callback

3

Ultimamente mi sono interessato ai futures, principalmente per la loro inclusione nello standard C ++, ma vedo che c'è un dibattito attivo sui futures rispetto a callback in molte aree di programmazione, come Node.js.

Mi piacerebbe chiedere se ci sono dei pattern / casi d'uso noti in cui i futures forniscono un chiaro vantaggio (in termini di leggibilità e facilità di implementazione) ai callback?

Sappiamo tutti i principali svantaggi associati ai callback: l'indirezione in termini di lettura del codice e le lambda potenzialmente profondamente annidate e confuse in linguaggi come Javascript.

Il vantaggio di utilizzare i futures è che eliminano il codice indiretto e ti permettono di scrivere codice in uno stile "sincrono", ma ti forniscono un gestore che ti permette di controllare lo stato di alcune operazioni in background. In questo senso, non penso che sarebbe troppo soggettivo / controverso sostenere che il futuro è un migliore sintattico con il modo in cui la mente umana tende a pensare (fai questo, fallo, fallo mentre aspetti questo, ecc.).

Tuttavia, quando in realtà uso i future in pratica, mi imbatto spesso nel seguente problema:

Un tipico caso d'uso per i futures è dove gestisci molte operazioni asincrone tramite una serie di oggetti futuri, come un vector<future> futures (usando la sintassi C ++). Penso che una chiave di lettura sia che i futures richiedono che attivamente controlli ogni operazione asincrona per vedere se è fatta, mentre con i callback passivamente attendi che ogni evento venga completato. Ma poiché, nel caso generale, non hai modo di sapere quale evento verrà completato per primo, potresti perdere un parallelismo se stai iterando su una serie di futuri e future[10] termina 5 secondi prima di future[0] , ma sei seduto lì in attesa del completamento di future[0] .

Possiamo attenuarlo con un tipo di operazione "wait_for" - invece di aspettare ogni futuro, possiamo aspettare un certo intervallo breve e poi procedere per continuare l'iterazione. Ma questo è fondamentalmente come un'attesa, consumando risorse aggiuntive della CPU. Con i callback, non è necessario eseguire alcuna operazione in quanto il codice di richiamata viene invocato passivamente da un reattore di eventi in background. Fondamentalmente, iterando su una serie di futuri nel codice dell'applicazione, si sta "ri-implementando" un reattore di eventi di sondaggio ad un livello più alto.

Un caso di utilizzo semplice per i futures che ho trovato è una situazione in cui si hanno una o più chiamate asincrone e si possono alternare alcuni cicli della CPU tra le chiamate. Si supponga di dover chiamare un servizio Web HTTP due volte, ma il risultato della prima chiamata offre l'opportunità di avviare immediatamente l'elaborazione senza dover attendere il completamento della seconda chiamata. I futures rendono questo facile, perché puoi semplicemente dire:

future result1 = some_remote_call();
object data = result1.get(); // wait for result1 to complete

future result2 = another_remote_call();

// ... do some processing here while we're still waiting on result2 ... //

Quindi questo è sicuramente un buon caso d'uso, ma il caso più comune di aspettare che si verifichino eventi N sembra più adatto per i callback, nonostante il codice-indiretto che subiamo usando i callback.

Quindi, quali sono alcuni modelli di utilizzo / casi d'uso noti in cui i futures offrono un chiaro vantaggio (in termini di leggibilità del codice e facilità di implementazione) rispetto ai callback?

    
posta Siler 05.12.2014 - 19:13
fonte

1 risposta

4

Quello che devi capire è che la libreria standard C ++ ha probabilmente la peggiore implementazione dei futuri concepibile dall'uomo. Quello che fa C ++ è poco più di un involucro debole attorno a un semaforo. La maggior parte delle implementazioni future incoraggiano estensivamente l'uso di callback lambda, per raggruppare più futuri insieme in modo asincrono utilizzando then e consente di creare facilmente un singolo futuro basato su una raccolta di altri futures. Non hanno nessuno dei problemi che stai sollevando qui.

Guarda Q per una delle migliori implementazioni, per vedere come i futures sono stati progettati per essere utilizzati. Se cerchi in giro, ci sono persone che portano queste idee in C ++. Non è terribilmente difficile da implementare.

    
risposta data 05.12.2014 - 20:24
fonte

Leggi altre domande sui tag