Il 0% ha trovato utile questo documento (0 voti)
2 visualizzazioni

C# 15.1 Threads intro

Il documento descrive il concetto di multithreading in C#, spiegando come i thread consentano l'esecuzione simultanea di parti indipendenti di un programma. Viene illustrata l'implementazione dei thread utilizzando il namespace System.Threading e viene fornito un esempio pratico di creazione e gestione di thread. Infine, si discute l'importanza della sincronizzazione tra thread e l'uso del metodo Join per garantire che il main thread attenda il completamento di un thread secondario.

Caricato da

alessandro121003
Copyright
© © All Rights Reserved
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
2 visualizzazioni

C# 15.1 Threads intro

Il documento descrive il concetto di multithreading in C#, spiegando come i thread consentano l'esecuzione simultanea di parti indipendenti di un programma. Viene illustrata l'implementazione dei thread utilizzando il namespace System.Threading e viene fornito un esempio pratico di creazione e gestione di thread. Infine, si discute l'importanza della sincronizzazione tra thread e l'uso del metodo Join per garantire che il main thread attenda il completamento di un thread secondario.

Caricato da

alessandro121003
Copyright
© © All Rights Reserved
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 6

INTRO 15.

1 C# Thread

15.1 C# Thread INTRO

GENERALITA'

Così come il meccanismo del multitasking permette di avere più processi (task) in
esecuzione contemporanea (pseudo-parallelismo), così il meccanismo del multithreading
permette di avere singoli processi che contengono più attività indipendenti (thread) in
esecuzione contemporanea.

Quando un programma è scritto per avere due o più parti di codice indipendente, si
parla di programma mulithreaded. Ciascuna parte indipendente è detta thread.Un
thread è quindi una unità di codice eseguibile in modo indipendente.

Le CPU multicore non possono esprimere tutta la loro potenza in assenza di programmi
multithreaded!!

Come sappiamo dalla teoria dei sistemi operativi

• il processo è usato dal sistema operativo per rappresentare le diverse


applicazioni (programmi) che possono essere eseguite.

• Il thread è l'unità alla quale è assegnata la CPU (il round-robin è fatto sui thread
e non sui processi).

• Un processo è un contenitore che comprende, tra le altre cose, i thread:

▫ se il programma, che ha dato origine al processo, non è multithreaded, allora il


processo contiene un solo thread, detto main thread, associato al programma (cioè
all'intero spazio di indirizzamento).

▫ se invece il programma è multithreded, il processo contiene il main thread (associato


al Main del programma) e tutti i thread associati alle parti di codice indipendente presenti
nel programma.

• Ogni thread ha un proprio stack di memoria e condivide, con gli altri


thread, lo heap

▫ La comunicazione tra thread (attraverso variabili condivise allocate nello stack


del main thread) è perciò più semplice rispetto a quella tra processi.

alessandra peroni Pag. 1 di 6


INTRO 15.1 C# Thread

IMPLEMENTAZIONE dei THREAD

Nella piattaforma .NET, il namespace System.Threading fornisce

• gli strumenti per la costruzione di applicazioni multithreaded:

▫ classi Thread, ThreadStart

• l'accesso ad una serie di thread gestiti dal CLR (dal sistema di runtime)

▫ classi Timer, Mutex, Monitor, Semaphore

La classe Thread è usata per costruire l'oggetto che racchiude in sé la parte di codice
indipendente. Una volta costruito l'oggetto Thread, è poi possibile usare i metodi per
far partire il thread, sospenderne l'esecuzione, fermarlo, distruggerlo...

OPERATIVAMENTE...

1. Creare una classe con il metodo che contiene il codice indipendente da


associare al thread

public class CodiceIndipendente{


// Questo è il metodo che contiene il codice da associare al thread
public void Attività()
{
while( true ) //ciclo infinito
{
Console.Write("y");
}
}
}

2. Nella classe Program (con il metodo Main) creare un oggetto di tipo


CodiceIndipendente e un oggetto Thread passando, al costruttore di
quest'ultimo, un oggetto ThreadStart che specifica il metodo da associare
al thread:

public class Program


{
public static int Main()
{
CodiceIndipendente codice = new CodiceIndipendente();
Thread th = new Thread(new ThreadStart(codice.Attività));
.........
}

alessandra peroni Pag. 2 di 6


INTRO 15.1 C# Thread

}
3. Far partire il thread creato: th.Start()

public class Program


{
public static int Main()
{
CodiceIndipendente codice = new CodiceIndipendente();
Thread th = new Thread(new ThreadStart(codice.Attività));
th.Start(); //il thread th è NATO!!!!

.........
}
}

NOTA ThreadStart è una classe delegato. Questa classe permette di instanziare


oggetti ai quali si passa, come parametro, il riferimento (indirizzo) a un metodo.
Questo oggetto può poi essere usato per richiamare il metodo corretto nel runtime,
quando l'indirizzo risulta noto. Un delegato è una classe cui si delega il compito di
“far qualcosa”. In questo caso le si delega il compito di chiamare il metodo “corpo
del codice del programma-thread”. Di quale thread? Quello che si sta creando th,
che deve eseguire codice.Attività.

Se osserviamo il programma che abbiamo scritto, possiamo notare che, quando ne


richiediamo l'esecuzione, viene generato un processo che contiene due thread: il main
thread e il thread secondario th. Così, il S.O. ha due thread di cui fare lo scheduling
(cioè da assegnare alla CPU o ai core della CPU multicore) . Possiamo poi osservare che:

• Il main thread termina appena dopo aver generato e mandato in esecuzione il thread th.

• th non termina mai.

Ecco una variante curiosa. Il main thread fa anche lui qualcosa. Eseguendo questo
programma, si vede in modo evidente il comportamento preemptive del sistema
operativo.

using System;
using System.Threading;
namespace ThreadZero
{
class Codice
{
public void Attività()

alessandra peroni Pag. 3 di 6


INTRO 15.1 C# Thread

{
for (int i=0 ; i<300 ; i++) //ciclo finito
Console.Write("y");
}
}
}
namespace ThreadZero
{
class Program
{
static void Main(string[] args)
{
Codice codice = new Codice();
Thread t = new Thread(new ThreadStart(codice.Attività));
t.Start(); // running Attività()

// il main thread fa la stessa cosa


for (int i=0 ; i<300 ; i++) //ciclo finito
Console.Write("x");
}
}
}

Ecco un possibile output:

alessandra peroni Pag. 4 di 6


INTRO 15.1 C# Thread

Perchè possibile? Perchè non c'è garanzia di quando un thread viene selezionato dallo
scheduler. Eseguire più volte il programma per verificare l'asserzione appena fatta.

alessandra peroni Pag. 5 di 6


INTRO 15.1 C# Thread

E' possibile far terminare il main thread solo dopo che il thread secondario è
terminato. Per ottenere questo comportamento si usa il metodo Join(), che è un
metodo che blocca il thread chiamante finchè un thread chiamato non è terminato.

Studiamo attentamente il codice del main thread qui sotto riportato.

public class Program


{
public static int Main()
{
CodiceIndipendente codice = new CodiceIndipendente();
Thread th = new Thread(new ThreadStart(codice.Attività));

th.Start(); //system call: il main thread chiede al S.O. di creare th

while(!th.IsAlive); //system call: il main thread aspetta finché th è vivo

Thread.Sleep(10); //system call: il main thread si sospende per (10 millisec), per
permettere a th di far qualcosa

th.Join(); //system call: il main thread aspetta che th sia terminato

Console.WriteLine(“main thread è terminato”);


}
}

NOTA: ricordarsi di mettere using System.Threading;

Per un thread è anche possibile chiedere la terminazione di un altro thread. Nel


codice precedente è ad esempio possibile inserire la seguente istruzione:

th.Abort(); //system call: il main thread chiede al S.O. di terminare th

appena prima di th.Join().

alessandra peroni Pag. 6 di 6

Potrebbero piacerti anche