Quali sono i modelli sottostanti nei sistemi che consentono operazioni asincrone?

2

Dire che sto lavorando con un sistema che consente operazioni asincrone e non bloccanti. Se accodo un set di quelle operazioni e specifichi i loro riferimenti al buffer dei risultati:

nonblocking_write( message, write_buffer );
nonblocking_read( source, read_buffer );
nonblocking_read( other_source, other_read_buffer );

wait();

// do stuff with results now in the buffers

o accodare lo stesso insieme di operazioni, ma specificare i callback dei risultati per eseguire direttamente i risultati con

nonblocking_write( message, write_handler );
nonblocking_read( source, read_handler );
nonblocking_read( other_source, other_read_handler );

// doing stuff happens in the result handlers, not here

La mia domanda riguarda la libreria o l'ambiente esponendo le operazioni nonblocking_*() . Quali strutture e modelli di software consentono questo tipo di cose per accadere?

Questi sono i miei pensieri finora:

  • In un ambiente con multithreading, genera un nuovo thread all'interno dell'operazione nonblock, quindi esegue un'operazione di blocco equivalente all'interno di quel thread.

  • In un singolo ambiente a thread, definire un costrutto event e tasks che gestiscono 'eventi', quindi eseguire operazioni non bloccanti, spingere event / task coppie in una coda per un ciclo di eventi da eseguire dopo. (Penso che questo è come JavaScript lo fa.)

posta kdbanman 10.03.2015 - 18:41
fonte

1 risposta

3

Dato che nessun altro ha risposto e ho avuto un giorno intero per ricordare tutti i miei vecchi corsi di compli, questa volta cercherò di scrivere una risposta adeguata.

Per quanto ne so, tutto il comportamento asincrono nei computer è implementato a un certo livello mettendo le cose in una coda e tornando in quella coda in seguito per elaborare le cose quando è più conveniente. Quando crei un thread, stai spingendo alcune informazioni di identificazione dei thread su una coda che risiede all'interno del kernel del sistema operativo. Quando si attiva un evento o si invia un messaggio - in ogni lingua e struttura a cui sono abituato - si sta spingendo un evento o un oggetto messaggio in una coda eventi o in una casella postale o in qualsiasi modo si desideri chiamarlo.

Naturalmente, il diavolo si trova nei dettagli (dell'implementazione) e ci sono molti dettagli.

  • Con Javascript, quello che ho appena detto è l'intera storia: il browser ha una semplice coda di eventi che risolve uno alla volta in ordine. In particolare, si presuppone che ogni gestore di eventi sia una singola chiamata di funzione che verrà semplicemente eseguita fino al completamento senza incidenti.

  • Con i thread del sistema operativo, non hai le funzioni da chiamare, ma le attività da eseguire per un determinato periodo di tempo. Quindi si ha un interrupt del timer hardware che costringe periodicamente la CPU ad eseguire la routine di scheduling del kernel del sistema operativo.

  • I socket di rete sono un po 'speciali perché la "coda" non è realmente una coda, in quanto non è FIFO o LIFO o qualsiasi altro ordine definito. Invece, il sistema operativo deve interrogare costantemente l'hardware di rete per vedere se ha nuovi dati e, quando lo fa, deve capire a chi appartengono quei dati, perché non ha modo di sapere a chi appartengono le richieste per prime. La "coda" è probabilmente più simile a una mappa dai numeri di porta ai contesti di esecuzione che devono essere ripresi quando i dati corrispondenti a quel numero di porta appaiono infine.

Va da sé che queste implementazioni hanno priorità molto diverse per quanto riguarda la stabilità, la prevedibilità, l'ottimizzazione e l'interoperabilità.

    
risposta data 11.03.2015 - 21:26
fonte