2016-06-15 17 views
9

Ho avuto un'interessante domanda di intervista oggi. Prendere in considerazione si ha la seguente applicazione di console:Cosa succede quando un'app di console .NET si blocca su Console.ReadLine()?

static void Main(string[] args) 
{ 
    Console.WriteLine("Hello world"); 
    Console.ReadLine(); 
} 

esecuzione Quando viene raggiunta la linea Console.ReadLine() viene sospesa e il programma attende per l'input da tastiera. Quanti thread ci sono a questo punto e in quali stati sono, ad es. In esecuzione, sospeso, ecc.?

Suppongo che l'intervistatore sia la consapevolezza/comprensione dei thread che costituiscono un'app console .NET e il modo in cui interagiscono con il sottosistema IO del sistema operativo sottostante.

+6

Per quanto riguarda l'applicazione è interessato, non v'è un solo thread. Se il sistema operativo crea thread aggiuntivi dietro le quinte, si tratta di dettagli di implementazione irrilevanti dal punto di vista dell'applicazione. –

+1

E 'Console.ReadLine();' blocca solo il thread in cui lo stai eseguendo. –

+0

L'intervistatore ha probabilmente qualche esperienza con il debug di WinDbg, https://www.jayway.com/2011/04/26/getting-started -with-managed-dump-files-using-windbg/in modo che lui/lei possa penetrare più in profondità nel processo e nei thread di te. Se si padroneggiano gli strumenti e i suggerimenti, tali domande non costituiranno un ostacolo in futuro. –

risposta

12

Non c'è un numero definito.

Il codice è in esecuzione su un solo thread, il thread principale. La chiamata a Console.ReadLine non crea un nuovo thread, avvia appena una richiesta I/O e attende che venga elaborata, non richiede thread, ma poiché si utilizza l'API sincrona, non è possibile rilasciare il thread, quindi blocca solo Se l'intervistatore voleva un solo numero, questo è il numero - è l'unico thread dell'applicazione che hai, tutto il resto è un dettaglio di implementazione.

Esistono molti thread di infrastruttura: i thread di Garbage Collector sono i principali e alcuni di questi vengono creati e distrutti tutto il tempo.

Infine, ci sono i fili da qualche parte nel mezzo - in particolare, il pool di thread. Poiché non si utilizza il pool di thread, avrà il numero predefinito di thread, a meno che la configurazione non indichi diversamente, di solito si tratta di due thread per core della CPU logica.

La realtà va ancora più in profondità. Ad esempio, i thread .NET sono thread gestiti e possono saltare tra i thread "nativi" alla volontà del runtime. Tuttavia, questo è qualcosa a cui non devi mai preoccuparti, a meno che tu non stia scrivendo il tuo runtime .NET o un sistema operativo :) Oppure, facendo un interop pesante con il codice nativo che dipende dall'affinità del thread nativo (di nuovo, non molto comune) .

Sospetto che lo scopo principale della domanda sia farvi parlare di come funziona il modello di threading di Windows, di come .NET gestisce i thread e di quali tipi di thread ci sono in una tipica applicazione Windows/.NET. Ma soprattutto, per farti parlare: P

+0

Per "saltare i thread nativi", intendi * creare *? È un uso idiomatico di skip che non ho familiarità con, o solo un refuso? –

+0

Capisco. Sì, "tra" chiarirebbe le cose. Salta, cambia, salta/cambia, quale. –

+0

Forse voleva sapere della discussione sul GC e così non può essere sicuro. Penso che stesse parlando solo di thread gestiti piuttosto che di thread del sistema operativo. Grazie comunque per la risposta. –

3

Sono d'accordo con Luuan, quindi, a seconda di cosa intendesse il tuo intervistatore, ci sono per esempio thread di VisualStudio in esecuzione oltre al thread principale. A proposito, questo thread può essere disabilitato (in VS2015: Proprietà progetto> scheda Debug> deselezionare Abilita processo di hosting di Visual Studio)

Se si utilizza Visual Studio, è possibile visualizzare i thread durante il debug.

Il codice in esecuzione:

static void Main(string[] args) 
{ 
    Console.WriteLine("Hello world");   
    Console.ReadLine(); 
} 

La Finestra Discussione (In VS2015: Debug -> Windows -> discussioni):

enter image description here

ho aggiunto un nuovo thread per il tuo esempio:

Il codice di marcia:

static void Main(string[] args) 
{ 
    Console.WriteLine("Hello world"); 
    new Thread(DoSomethingElse).Start();    
    Console.ReadLine(); 
} 

private static void DoSomethingElse() 
{ 
    while (true) 
    { 
     Thread.SpinWait(100); 
    } 
} 

La finestra Discussione:

enter image description here

+0

Lo scenario era che esegui l'eseguibile dalla riga di comando - ho dimenticato di dirlo, quindi non penso che intendesse i thread VS aggiuntivi. –