Il codice asincrono, non bloccante, dovrebbe anche costare più o meno la stessa quantità di memoria, perché il callstack dovrebbe essere salvato da qualche parte proprio prima di eseguire la chiamata asincrona (il contesto viene salvato, dopotutto).
L'intera stack di chiamate è non salvate quando si verifica un await
. Perché credi che l'intero stack di chiamate debba essere salvato? Lo stack di chiamate è la reificazione della continuazione e la continuazione di l'attività attesa non è la continuazione di l'attesa. La continuazione dell'attesa è in pila.
Ora, è possibile che, quando è stato atteso ogni metodo asincrono in un determinato stack di chiamate, le informazioni equivalenti allo stack di chiamate siano state memorizzate nelle continuazioni di ciascuna attività. Ma il carico di memoria di tali continuazioni è memoria heap raccolta dati inutili, non un blocco di un milione di byte di memoria stack impegnata. La dimensione dello stato di continuazione è l'ordine n nella dimensione del numero di attività; il peso di un thread è di un milione di byte sia che lo si usi o meno.
se le discussioni sono significativamente inefficienti (memoria-saggio), motivo per cui non l'OS/CLR offrire una versione più leggera di fili
Il sistema operativo fa. Offre fibre. Certo, le fibre hanno ancora uno stack, quindi forse non è meglio. Suppongo che potresti avere una discussione con una piccola pila.
Non sarebbe una soluzione molto più pulito al problema di memoria, invece di costringere a ri-architettura nostri programmi in modo asincrono
Supponiamo fatto fili - o per quella materia , processi - molto più economico. Ciò non risolve ancora il problema della sincronizzazione dell'accesso alla memoria condivisa.
Per quello che vale, penso che sarebbe bello se i processi fossero più leggeri. Loro non sono.
Inoltre, la domanda in qualche modo si contraddice. Stai lavorando con i thread, quindi sei già disposto ad assumerti l'onere della gestione delle operazioni asincrone. Un determinato thread deve essere in grado di dire un altro thread quando ha prodotto il risultato richiesto dal primo thread. Il threading implica già l'asincronia, ma l'asincronia non implica il threading. Avere un'architettura asincrona integrata nel linguaggio, il runtime e il sistema dei tipi avvantaggia solo le persone che hanno la sfortuna di dover scrivere codice che gestisce i thread.
Poiché modo oltre il 95% del ciclo di vita del filo viene speso per dormire (supponendo applicazioni IO-bound qui), il calo di prestazioni dovrebbe essere trascurabile, poiché le sezioni di trattamento del filo sarebbe probabilmente non può essere anticipata dal sistema operativo perché dovrebbero funzionare molto velocemente, facendo pochissimo lavoro.
Perché dovresti assumere un lavoratore (thread) e pagare il loro stipendio per sederti vicino alla casella di posta (dormendo il thread) in attesa che arrivi la posta (gestendo un messaggio di I/O)? Gli interrupt IO non hanno bisogno di un thread in primo luogo. Gli interrupt IO esistono in un mondo al di sotto del livello dei thread.
Non assumere un thread per attendere IO; lasciare che il sistema operativo gestisca operazioni IO asincrone. Assegna le discussioni per fare quantità enormi di elaborazione CPU ad alta latenza e quindi assegnare un thread a ciascuna CPU che possiedi.
Ora veniamo alla tua domanda:
Quali sono i vantaggi di asincrona del codice (non bloccante)?
- Non bloccare il thread UI
- Rendere più facile scrivere programmi che vivono in un mondo con latenza elevata
- un uso più efficiente delle risorse della CPU limitate
Ma lasciatemi riformulare la domanda usando un'analogia. Stai gestendo una società di consegna. Ci sono molti ordini in arrivo, molte consegne che escono e non si può dire a un cliente che non si prenderà la consegna fino a quando tutte le consegne non saranno state completate.Che è meglio:
noleggio cinquanta ragazzi a prendere le chiamate, raccogliere pacchetti, le consegne di pianificazione, e consegnare i pacchi, e quindi richiedono che 46 di loro essere inattivo in ogni momento o
noleggio quattro ragazzi e ciascuno di loro è davvero bravo in un primo momento, fa un po 'di lavoro alla volta, in modo che siano sempre pronti a rispondere alle richieste dei clienti e, in secondo luogo, è davvero bravo a tenere una lista di lavori di cui ha bisogno fare in futuro
Quest'ultimo sembra un affare migliore per me.
Non tutti i thread sono uguali qui. Il blocco del thread dell'interfaccia utente non funziona perché l'app non risponde. –
Se * si desidera * avere un codice di blocco a thread singolo, allora * sicuramente * può *. La maggior parte delle applicazioni moderne preferisce non farlo. Considera un processo in background in un'app desktop in cui desideri ancora poter interagire con l'interfaccia utente (ad esempio fornire un indicatore di avanzamento sul processo). O un'applicazione web con un throughput elevato ma pesanti operazioni di back-end, dove legare un thread del server per attendere un'operazione riduce drasticamente il numero di utenti simultanei possibili. – David
Prova ad applicare i tuoi argomenti sia ad un'applicazione desktop con un'interfaccia utente reattiva che ad un'applicazione web scalabile a molte richieste –