Newsgroup: it.comp.programmare.win32
Titolo: Scusate l'ignoranza che cosa sono i THREAD

Buongiorno a tutti, scusate la domanda forse banale, ma continuo a sentire
parlare di THREAD, qualcuno mi spiega che cosa sono, che cosa servono, tutto
quello che c'è da sapere sull'argomomento.
Grazie a tutti per le risposte .Andrea



un thread é un processo molto leggero, creato da un processo padre (il
tuo programma...) affinché svolga un compito in maniera separata senza
ostacolare l'esecuzione del programma padre..
Pensa per un istante ad un programma che controlla se l'utente ha
premuto un tasto sulla tastiera e contemporaneamente deve verificare
che l'input non provenga dal mouse +tosto......
Creerai due thread i quali segnaleranno al padre attraverso un msg,
oppure richiamando una funzione della scelta dell'utente....
questo modo di dirti cosa é un thread é stupido....
però spero ti faccia capire qualcosa
cod
p.s.
se qualcuno viene a dirmi che la tastiera e il mouse generano
un segnale di interruzione .... lo so, io ho fatto solo un esempio!

> Grazie a tutti per le risposte .Andrea
c> un thread é un processo molto leggero,
Non proprio. In Windows un processo ha almeno un thread (uno o più) ma
un processo  non è un thread.   E' un "flusso  di esecuzione separato"
che  in teoria  può procedere  in contemporanea  al thread  che  lo ha
generato.   In pratica  ciò può  avvenire  solo con  macchine a  molti
processori ma nella vita comune  capitano molte situazioni in cui sono
comodi: ad esempio un thread si occupa di fare calcoli molto lunghi ed
un'altro di tenere aggiornata  l'interfaccia utente. In questo caso il
secondo thread  viene svegliato solo dalla presenza  di messaggi nella
coda (e quindi spesso "dorme"  lasciando la CPU libera) mentre l'altro
continua  i  suoi  calcoli.  Per  me su  "Programmazione  Avanzata  In
Windows"  (Richter,   Microsoft  Press)  trovi   le  informazioni  che
cerchi...
Se  poi  vuoi il  significato  Usenet  :), un  thread  è  un filo  del
discorso, un insieme di messaggi tutti sullo stesso argomento.
--
Gian Uberto| main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Lauri      |                        David Korn, 1987 ioccc best one liner 
(aka saint)|-------------------------------------------------------------------
em@ail: 
sa...@eng.it
 ( vedere X-nospam nello header - see X-nospam in header )

 writes:
GUL> Se  poi  vuoi il  significato  Usenet  :), un  thread  è  un filo  del
GUL> discorso, un insieme di messaggi tutti sullo stesso argomento.
OOOPS.... era per Marchioni...


 generato.
La tua precisazione č corretta, ma quanto ha detto cod non č del tutto
errato. Anche Tanenbaum definisce un thread come un "processo leggero" ...
forse andrebbe spiegato il perchč viene definito cosě, parlando del fatto
che i thread non dispongono di un loro spazio di indirizzamento etc...
Ciao
--
- Carlo -
c.b...@libero.it

errato. Anche Tanenbaum definisce un thread come un "processo leggero" ...
Dipende dalle scelte di implementazione.
Ci sono sistemi operativi in cui i thread sono creati e
gestiti, effettivamente, come cio' che AST chiama
"lightweight processes".
--
CyberWalkie - walkietalkie(at)
libero.it

generato.
Occhio a non confondersi con cio' che si intende,
comunemente, con "processo".  
Tu parli di "procedere" per un thread e la logica vuole che
siano i processi a procedere.
Non e' sbagliato definire un thread un processo, proprio
perche' procede per via indipendente.
Poi, volendosi attenere ai termini formali e' giusto
distinguere.  
I thread possono giustamente definirsi come dei percorsi di
esecuzione separati e paralleli.  
Un processo, invece, in memoria esiste solo come
"contenitore" di thread (giusto lo spazio per il suo oggetto
kernel).  
Il thread primario puo' generare altri thread che procedono
in contemporanea ad esso.
--
CyberWalkie - walkietalkie(at)
libero.it

 cosa servono, tutto quello che c'è da sapere sull'argomomento.
I thread sono processi (ossia codice in esecuzione) che condividono lo 
stesso spazio di indirizzamento, cioè hanno in comune le variabili 
globali, lo heap (ossia le variabili gloabali e dinamiche), possono 
scambiarsi puntatori a locazioni di memoria, eccetera. Ogni thread ha 
comunque un proprio stack (ossia variabili locali e parametri di 
funzioni) e un proprio contesto (ossia un set di registri del 
processore). Un'importante limitazione è che ogni processore può 
eseguire al massimo un thread alla volta
I thread funzionano in modo molto diverso a seconda dei sistemi 
operativi. Ecco qualche esempio:
DOS, Windows 16bit:
  Tutti i programmi in esecuzione vengono considerati dei thread. In 
pratica, tutti i programmi possono scambiarsi puntatori a memoria, hanno 
in comune tutte le variabili globali, e possono leggere e scrivere 
ovunque nella memoria. Il sistema operativo stesso è uno di questi 
thread, quindi qualsiasi programma può ostacolarne il funzionamento. Non 
esiste il concetto di memoria virtuale: l'indirizzo 0, ad esempio, punta 
realmente al primo byte della RAM
  In DOS nulla viene fatto per permettere a più programmi di essere 
eseguiti contemporaneamente (ma esiste un driver per DOS che aggiunge 
questa capacità), in Windows inizialmente si risolse con una funzione di 
sistema, chiamata Yeld: ogni programma doveva chiamare periodicamente 
questa funzione per permettere l'esecuzione di un altro programma - ma 
era pur sempre libero di non chiamarla mai, e bloccare tutti gli altri 
programmi
Windows 32bit:
  Nasce la distinzione tra processi e thread. I thread non condividono 
più tutti quanti lo stesso spazio di indirizzamento, ma vengono separati 
in unità (spazi di indirizzamento) chiamate processi. Ogni volta che 
viene avviato un programma, viene prima creato un oggetto-processo per 
quel programma, poi viene creato un oggetto-thread, dopodichè può 
iniziare l'esecuzione
  I thread non devono più preoccuparsi di pensare al proprio scheduling 
("pianificazione", ossia il meccanismo per superare la limitazione di un 
thread per processore), il sistema se ne occupa automaticamente, 
passando l'esecuzione da un thread all'altro quando necessario, dando 
eventualmente maggiore priorità a certi thread piuttosto che altri
  E' sempre possibile comunque usare il vecchio sistema, ossia lo 
scheduling manuale, trasformando i thread in oggetti chiamati fibre, ma 
è possibile imporlo solo a livello di singolo processo, non dell'intero 
sistema
UNIX:
  Ogni programma in esecuzione è un thread. Ogni thread ha però il 
proprio spazio di indirizzamento personale, per questo motivo ci si 
riferisce ad essi chiamandoli processi. In conseguenza di questa 
definizione, ogni processo può avere al massimo un thread, ed esistono 
essenzialmente due modi per superare questa limitazione:
   - creare un processo figlio, usando la funzione fork(). Il processo
     figlio eredita lo heap del genitore e persino il punto di 
     esecuzione, ma essendo eseguito in uno spazio di indirizzamento
     separato lo heap è solo una copia - in pratica modificando una
     variabile globale nel figlio, il genitore non ne è affetto
   - creare dei sotto-thread usando le funzioni della famiglia pthreads 
     (POSIX threads). Questi thread non vengono schedulati dal sistema
     operativo: la loro gestione ricade interamente nelle mani del 
     processo che li crea (ma la cosa avviene trasparentemente, 
     all'interno di pthreads). Non solo: due programmi potrebbero usare
     due versioni completamente diverse di pthreads, per questa ragione
     non è possibile elencare nè contare i thread di un processo - i
     thread sono un suo "affare privato", e non, come in Windows,
     oggetti del kernel
Quali sono le implicazioni del multithreading, ossia di programmi con 
più thread?
 - accedere alle variabili globali diventa pericoloso. Nel momento in 
cui un thread sta leggendo una stringa, la sua esecuzione potrebbe 
essere interrotta, e il controllo potrebbe essere passato ad un altro 
thread che riscrive quella stringa, rendendo completamente inutili i 
dati già letti dal primo thread
 - le operazioni bloccanti su file, inclusi i printf, ritardano 
anormalmente la ri-schedulazione di un thread, "sballando" la 
sincronizzazione con i suoi "compagni"
Come si risove? è semplice: si usano particolari oggetti, chiamati 
"oggetti di sincronizzazione", per bloccare certi thread (anche di altri 
processi - gli oggetti infatti possono essere resi globali, a livello di 
sistema) in attesa che determinate condizioni si verifichino, o per 
regolare l'accesso a variabili globali. Gli oggetti di sincronizzazione 
disponibili in Windows sono:
 - Semafori: sono oggetti con un contatore interno, che va da zero ad un 
   numero stabilito al momento della loro creazione. Ogni volta che un 
   thread richiede il possesso di un semaforo, se il valore del 
   contatore è  minore del tetto massimo, l'esecuzione del thread 
   prosegue, e il contatore viene incrementato di 1. Se il valore del 
   contatore è uguale  al tetto massimo, il semaforo è "rosso", e il 
   thread che ha richiesto il possesso del semaforo rimane in attesa che 
   si liberi un posto, ossia che un thread in possesso di quel semaforo 
   liberi il proprio posto, decrementando il contatore di 1. I semafori 
   vengono usati per permettere a un determinato numero massimo di 
   thread di accedere ad una risorsa condivisa
 - Mutex: esattamente come i semafori, ma il tetto massimo del contatore 
   è fissato ad 1, ossia un solo thread alla volta può essere in 
   possesso dell'oggetto, gli altri si mettono in fila e aspettano
 - Sezioni critiche: come i mutex, ma valgono unicamente all'interno del 
   processo che le crea. Hanno il vantaggio di essere molto più 
   "leggere" dei mutex, sono quindi l'ideale se c'è unicamente bisogno 
   di sincronizzare tra di loro i thread di un unico processo
 - Eventi: i thread che vogliono sapere quando un determinato evento si 
   verificherà si mettono in "ascolto" dell'evento, e rimangono bloccati 
   in attesa finchè un altro thread non "segnala" l'evento. In base agli 
   attributi dell'evento (manual-reset o auto-reset), alla sua 
   segnalazione possono essere liberati o uno o tutti i thread in 
   ascolto
 - Timer: come un evento, ma la sua segnalazione avviene automaticamente 
   (periodicamente ad intervalli o allo scoccare di una certa ora) in
   base all'orologio di sistema
Inoltre questi oggetti vengono utilizzati anche per trasformare in 
oggetti di sincronizzazione oggetti che non lo sono, ma che è comodo 
considerare tali, come ad esempio:
 - processi e thread: è possibile attendere la terminazione di un 
   processo o un thread come se si trattasse di un evento
 - buffer di input delle console: due programmi testuali che condividono  
   la stessa console possono ottenere l'accesso esclusivo all'input 
   della console, per impedire di "rubarsi" l'input a vicenda 
   (possibilissimo se uno dei due programmi sta leggendo in modalità 
   linea e l'altro in modalità carattere. Se scrivessimo "format A:" e 
   dessimo invio, il primo programma leggerebbe solo "ormat A:", perchè 
   il primo carattere è stato letto dal secondo programma)
Windows ha un set di funzioni estremamente complesso riguardo alla 
sincronizzazione, e oltre ai già citati oggetti, possiamo avvalerci dei 
seguenti meccanismi:
 - input/output asincrono: le funzioni di lettura-scrittura su file
   possono essere chiamate in modo da ritornare immediatamente, ed
   essere completate in background. Per sapere quando un'operazione
   viene effettivamente completata si crea un evento, lo si passa alla 
   funzione di I/O, e si attende che l'evento venga segnalato, oppure si 
   usa un oggetto di tipo OVERLAPPED, specifico per le funzioni di I/O
 - chiamate asincrone a procedura (APC): ogni thread ha una coda di 
   funzioni che verranno chiamate in ordine FIFO (First In, First Out - 
   ossia verranno chiamate nello stesso ordine in cui sono state 
   aggiunte alla coda) non appena il thread si metterà in stato di 
   attesa. Chiamata l'ultima funzione, la coda viene svuotata, e la 
   funzione usata dal thread per mettersi in attesa ritornerà un valore 
   indicante che l'attesa è stata interrotta da una APC
 - accesso interdipendente a variabili (Interlocked Variable Access):
   una serie di funzioni che forniscono un modo relativamente semplice
   per sincronizzare l'accesso di più thread ad una o più variabili
   globali
 - deposito locale thread (Thread Local Storage): ogni thread può avere
   un massimo di 64 variabili, utilizzabili come se fossero globali, ma
   in realtà ogni thread ne conserva la propria copia privata

ma un processo  non è un thread.
beh, lui ha semplicemente dato la definizione "accademica" di thread, 
quella che troviamo anche in "Architettura dei computer", di A.S. 
Tanenbaum:
"Questi *thread* sono processi con uno stato molto ridotto (chiamati 
quindi "leggeri", lightweight) che condividono lo spazio di 
indirizzamento e tutto ciò che vi è associato[...]"

> generato.
C> Occhio a non confondersi con cio' che si intende,
C> comunemente, con "processo".  
Sotto windows un processo (o task)  è un insieme formato da uno spazio
di indirizzamento ed uno o più processi. 
C> Tu parli di "procedere" per un thread e la logica vuole che
C> siano i processi a procedere.
No.   L'evoluzione  è  legata  all'esecuzione.   In  architetture  non
multithreading  (i.e. i  vecchi Unix,  i  VAX...)  era  il processo  a
procedere  (o  evolvere).  Quando  hai  un solo  thread  per  processo
l'evoluzione di uno si identifica con quella dell'altro.
Ma  può  esserci la  situazione  patologica  di  trhead ad  evoluzione
ciclica che evolvano senza  far evolvere il programma (i.e. continuano
ad operare su eventi ininfluenti  al programma...)


di indirizzamento ed uno o piů processi. 
Definizione ricorsiva ?
Temo tu intenda dire : "da uno spazio di indirizzamento e
uno o piu' thread".
Questo lo sappiamo tutti qui dentro ed e' esattamente cio'
che ho detto nel mio messaggio.  Poi, cio' che si intende
COMUNEMENTE per processo non e' cio' che WINDOWS intende per
processo (visto che e' un s.o. specifico).  Tant'e' vero che
con processo si intende, comunemente (e non formalmente), il
thread primario del processo.  Poi, come ho detto nel mio
messaggio, attenendosi ai termini formali propri di ogni
s.o., si puo' intendere con processo qualcosa di diverso.
--
CyberWalkie - walkietalkie(at)
libero.it

> di indirizzamento ed uno o piů processi. 
C> Definizione ricorsiva ?
O fusione della materia grigia...
C> Temo tu intenda dire : "da uno spazio di indirizzamento e
C> uno o piu' thread".
Temi perché se č cosě arriva l'orco cattivo :) :) :) ?
