Upload
majong-devjfu
View
2.487
Download
0
Embed Size (px)
Citation preview
1
Svantaggi legati all'uso di processi• La gestione tradizionale dei processi può
diventare molto onerosa dal punto di vista computazionale– Creazione: allocazione dello spazio di
indirizzamento, e successiva popolazione– Context switch: salvataggio e ripristino degli
spazi di indirizzamento (codice, dati, stack) di due processi
• Con una applicazione con molti processi (server), il SO rischia di passare la maggior parte del tempo a svolgere operazioni interne di gestione, piuttosto che ad eseguire codice applicativo
2
Svantaggi legati all'uso di processi• La nozione classica di processo ingloba due
concetti ben distinti, gestiti dal SO:– Gestione delle risorse: ciascun processo ha
assegnati un proprio spazio di indirizzamento (solitamente, indipendente) ed alcune risorse
– Esecuzione traccia: ciascun processo esegue porzioni di codice sequenzialmente e concorrentemente con altri processi
• La gestione dell'esecuzione di una traccia non comporta particolari aggravi computazionali, essendo direttamente gestita dal processore
• La lentezza della gestione risiede nella complessità della gestione delle risorse del processo
3
Separazione risorse-esecuzione• Nei SO moderni, i due concetti ora visti
possono essere disaccoppiati– L'unità base di esecuzione di una traccia prende
il nome di thread– L'unità base proprietaria delle risorse prende il
nome di processo
• Ciascun processo può essere visto come:– un contenitore di risorse– un contenitore di codice– Uno strumento per far partire tracce sequenziali
(“fili” di codice, thread) di esecuzione del codice
4
Thread• Un thread è l'insieme dei dati utilizzati per
eseguire, in maniera concorrente, più tracce relative al codice di un processo
• Tutti i thread generati da un processo ne condividono il codice e le risorse
• In tal modo, le operazioni di gestione non toccano praticamente più lo spazio di indirizzamento!– L'aggravio di gestione si riduce sensibilmente
• Un SO in grado di gestire i thread è detto multithreaded
• Tutti i SO moderni supportano il multithreading
5
Ambiente a processi (single threaded)• Ciascun processo
contiene tutte le informazioni per poterlo eseguire
• Ambiente single threaded: ciascun processo può eseguire al più una traccia
• Informazioni:– Spazio indirizzi– Risorse prenotate– Registri interni
PCBfile
IP
dati
stack
codice
traccia inesecuzione
processo
6
Ambiente multithreaded• Ciascun processo
contiene tutte le informazioni per poterlo eseguire
• Ambiente multithreaded: ogni thread esegue tracce di codice
• TCB: Thread Control Block (simile a PCB)– Registri, Stack– Variabili “locali”– Stato esecuzione
PCBfile
IPcodice
processo
dati
TCB TCB TCB
IP stack IP stack IP stack
traccia inesecuzione
traccia inesecuzione
traccia inesecuzione
7
Processi vs. Thread
Processo Thread
8
Benefici del multithreading• Reattività
– Il blocco di un thread non inficia gli altri– Maggiore fluidità di esecuzione
• Condivisione risorse– I thread condividono la memoria e le risorse del
processo che li ha generati
• Economia– Alloco e distruggo risorse di processo una volta
• Architetture SMP– I thread eseguono in parallelo sui diversi
processori– Il singolo processo non li può sfruttare
9
Problemi del multithreading• Modello di programmazione complesso
– La condivisione delle risorse e della memoria implica spesso la gestione della concorrenza degli accessi a queste ultime
– Ulteriori passi di programmazione, spesso complessi
• Debugging complesso– E' molto difficile riprodurre bug in presenza di
accessi concorrenti alle risorse– E' spesso difficile individuare le cause del bug
10
Applicazioni del multithreading• Quali applicazioni si lasciano implementare
tramite i thread? Tutte quelle applicazioni:– che possono essere spezzate in più parti da
eseguire concorrentemente/parallelamente– in cui alcune parti si bloccano spesso per fare I/
O, mentre altre no– che devono gestire eventi asincroni (bottone
STOP del browser)
11
Supporto del SO ai thread• Il SO deve fornire un supporto per la gestione
dei thread– Supporto allo user level, tramite librerie di
funzioni (API) per gestire n thread in esecuzione– Supporto al kernel level, tramite una astrazione
di traccia di esecuzione
• Le diverse implementazioni di supporto ai thread svariano da un estremo all'altro– Implementazioni puramente a livello applicativo– Implementazioni puramente a livello kernel– Implementazioni “miste”
• Adozione di molteplici modelli di multithreading
12
Modello Many-to-One (N:1)• A più supporti user level corrisponde un solo
supporto kernel level– Il kernel vede una sola traccia di esecuzione,
ossia solo un processo che esegue– Il processo usa delle funzionalità applicative per
simulare uno scheduler di mini-processi– I mini-processi non sono noti al kernel del SO– Ciascun mini-processo è, in realtà, una
astrazione per eseguire una traccia di una funzione del processo
• Implementazioni: Green threads (Solaris), GNU Portable Threads, Java threads, Ruby threads
13
Modello Many-to-One (N:1)
Userspace
Kernelspace
Threadlibrary
p
Thread
ProcessoMain
Create, stop, schedule,resume, destroy
Thread Thread
PCB
14
Modello Many-to-One (N:1)• Vantaggi
– Gestione efficientissima dei thread (non viene coinvolto lo scheduler del kernel)
– Non richiede un kernel multithreaded per poter essere implementato
• Svantaggi– Se un thread effettua una chiamata bloccante, il
processo si blocca, e con esso tutti i thread– I thread sono legati allo stesso processo, e non
possono eseguire su processori fisici distinti
15
Modello One-to-One (1:1)• Ad un supporto user level corrisponde un
supporto kernel level– Il kernel vede una traccia di esecuzione distinta
per thread; ho l'analogo di un PCB per ciascun thread in esecuzione
– Il processo usa una system call simile a fork() per invocare il meccanismo di creazione
– I thread vengono schedulati dallo scheduler del kernel, come tutti gli altri processi
• Implementazioni: GNU/Linux (LinuxThreads, NPTL), Windows 95/98/2000/XP/NT
16
Modello One-to-One (1:1)
Userspace
Kernelspace
p
Threadfunction
Processo
Main
Create,destroy
PCB
Thread
PCB TCB
f
Threadfunction
Thread
TCB
17
Modello One-to-One (1:1)• Vantaggi
– Se un thread effettua una chiamata bloccante, non blocca gli altri thread
– I thread sono rappresentati da altrettanti TCB, e possono essere eseguiti su processori fisici distinti
• Svantaggi– Gestione meno efficiente dei thread (usa lo
scheduler del kernel)– Richiede un kernel multithreaded per poter
essere implementato
18
Modello Many-to-Many (N:M)• Ad N supporti user level corrispondono M
supporti kernel level (N>M)– Unione del modelli 1:1 ed N:1; intende prendere
il meglio dei due modelli– Il processo usa una system call simile a fork()
per creare M thread kernel level– Ciascuno di questi M kernel level thread crea N/
M thread user level
• Implementazioni: IRIX, HP-UX, Tru64 UNIX, Solaris (fino a V.9)
19
Modello Many-to-Many (N:M)
Userspace
Kernelspace
p
PCBPCB TCB
Threadlibrary
Thread
Processo
Main
Create, stop, sched,resume, destroy
Thread Thread
Create,destroy
Threadlibrary
Thread
Processo
Main
Create, stop, sched,resume, destroy
Thread Thread
20
Quando si applicano i modelli?• Modello Many-to-One
– Buono per applicazioni di tipo parallelo con pochissimo I/O
– Lo scheduler del kernel non le rallenta– Thread non schedulabili su più processori
• Modello One-to-One– Ideale per applicazioni di tipo parallelo o
distribuito con tanto I/O (server)– Mantiene elevato il grado di concorrenza– Ha soppiantato tutti gli altri modelli
• Modello Many-to-Many– Concepito per applicazioni suddivise in una
parte I/O (1:1) ed in una parte di calcolo (M:1)
21
Multithreading: creazione/immagine• In un programma multithreaded la semantica
delle operazioni fork() ed exec() cambia• Se un thread invoca la chiamata fork():
– può duplicare se stesso– può duplicare l'intero gruppo di thread
• Se un thread invoca la chiamata exec():– Sovrascrive l'immagine di tutti i thread e del
processo invocante
• Solitamente, si evita l'uso della exec() in ambiente multithreaded– Si associano i thread a funzioni che devono
essere eseguite
22
Multithreading: cancellazione• La cancellazione è l'operazione di terminazione
prematura di un thread• Il thread selezionato per una cancellazione è
chiamato thread bersaglio (target thread)• La cancellazione del target bersaglio può
avvenire in due modalità distinte:– cancellazione asincrona: un altro thread uccide
direttamente il thread bersaglio– cancellazione differita: il thread bersaglio
controlla periodicamente (cancellation point) se deve terminare, in modo da uscire in maniera pulita
23
Multithreading: gestione segnali• In ambiente single threaded, il segnale viene
inviato ad un processo• In ambiente multithreaded, a quale thread va
inviato il segnale?– al thread cui il segnale si riferisce– a ciascun thread (CTRL-C)– a specifici thread
♦ il primo thread che non blocca il segnale♦ Identificato dal TID
– ad un thread speciale, di controllo (Solaris 2)
24
Multithreading: thread pool• All'aumentare del numero di flussi concorrenti,
le risorse del sistema possono esaurire rapidamente
• Per impedire l'esaurimento delle risorse, un software multithreaded pre-crea un insieme di thread (thread pool)– Quando viene lanciato un thread, lo si preleva
dal gruppo– Quando un thread termina, lo si restituisce al
gruppo– Le operazioni di creazione/distruzione sono
molto più veloci– Si limita il numero di thread in esecuzione
25
Multithreading: Thread Specific Data• In particolari circostanze, ciascun thread può
necessitare di una copia privata di alcuni dati, detti dati specifici (thread locale)– Variabili “globali” per thread– Variabili “static” per thread
• La maggior parte delle librerie pthread forniscono il supporto per i thread locale
26
Modelli di programmazione• L'uso dei thread permette l'implementazione
efficiente di alcuni modelli di programmazione• Modello Pipeline:
– I thread eseguono “a catena”, uno dopo l'altro
• Modello Master-Slave:– Il thread master coordina l'esecuzione dei
thread slave (che effettuano il lavoro vero e proprio)
• Modello Worker:– Tutti i thread lavorano
27
Modelli di programmazione
Pipeline
Master-Slave
Worker
M
S S S
WW
WW
28
Librerie di threading• Ciascuna implementazione del supporto ai
thread fornisce una libreria di funzioni (thread library) per la gestione dei thread– La libreria può fare uso nullo, parziale o
completo delle funzionalità offerte dal kernel
• Implementazioni:– Pthreads: standard POSIX, kernel level– Win32: kernel level– Java: user level
29
Libreria Pthreads• Standard ANSI/IEEE POSIX 1003.1
– Gestione thread: creazione, distruzione, sincronizzazione
– Gestione concorrenza: meccanismo dei mutex– Comunicazione concorrente: meccanismo per
creare, distruggere e segnalare thread sulla base dei valori di specifiche variabili condizione (condition variables)
• Più di 60 funzioni per gestire thread come tipi di dato opachi (pthread_t)
• Concepita per i linguaggi C, C++• Compilazione: gcc -pthread
– include <pthread.h>
30
Creazione thread• Signature: int pthread_create(
pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);– Descrizione: crea un nuovo thread, eseguente
la funzione start_routine con argomento arg– Ingresso:
♦ Un puntatore alla struttura thread identificante il thread da eseguire
♦ Un puntatore alla struttura “attributi” che imposta le caratteristiche del thread (NULL)
♦ Un puntatore alla funzione start_routine♦ Un puntatore all'argomento arg
31
Creazione thread• Signature: int pthread_create(
pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);– Descrizione: crea un nuovo thread, eseguente
la funzione start_routine con argomento arg– Ritorno:
♦0 -> tutto ok– Il TID del thread appena creato è salvato
all'interno della struttura dati thread♦!=0 -> errore
– tipicamente, le risorse del sistema sono insufficienti per la creazione di un thread
32
Creazione thread• Un thread, a sua volta, può creare altri thread con
la pthread_create()
• Non esiste gerarchia o dipendenza fra I vari thread
33
Terminazione thread• Le cause di terminazione di un thread sono
molteplici– Il thread ritorna dalla funzione– Il thread invoca una chiamata di funzione
pthread_exit()– Il thread è cancellato da un altro thread tramite
la funzione pthread_cancel()– Il processo invocante carica un'altra immagine
con la funzione exec()– Il processo invocante esce tramite la funziona
exit()
34
Terminazione thread• Signature: void pthread_exit(void *retval);
– Descrizione: termina l'esecuzione del thread invocante
– Ingresso:♦un puntatore ad una variabile in cui sarà
scritto il codice di uscita del thread (potrà essere consultato tramite la pthread_join())
– Ritorno: nessuno
35
Attributi dei thread• Ad un thread è associata una struttura dati
identificante le sue proprietà (attributi): pthread_attr_t
• Tale struttura contiene una maschera di bit, che rappresenta le proprietà attivate
• Alcune proprietà:– Thread “joinabile”– Algoritmo di scheduling utilizzato– Scope delle variabili
36
Attributi dei thread• Signature: int pthread_attr_init(pthread_attr_t
*attr);– Descrizione: inizializza una struttura
pthread_attr_t– Ingresso:
♦un puntatore ad una struttura pthread_attr_t– Ritorno:
♦Sempre 0
37
Attributi dei thread• Signature: int pthread_attr_destroy
(pthread_attr_t *attr);– Descrizione: resetta una struttura pthread_attr_t
e rilascia le risorse allocate– Ingresso:
♦un puntatore ad una struttura pthread_attr_t– Ritorno:
♦Sempre 0
38
Attributi dei thread• Signature: int pthread_set_detachstate
(pthread_attr_t *attr, int detachstate);– Descrizione: imposta il flag “detached” del
thread con proprietà attr al valore detachstate– Ingresso:
♦Un puntatore ad una struttura pthread_attr_t♦Lo stato desiderato
(PTHREAD_CREATE_JOINABLE)– Ritorno:
♦0: -> tutto OK♦!=0: un errore
39
Attributi dei thread• Signature: int pthread_set_detachstate
(pthread_attr_t *attr, int detachstate);– Descrizione: imposta il flag “detached” del
thread con proprietà attr al valore detachstate– Ingresso:
♦Un puntatore ad una struttura pthread_attr_t♦Lo stato desiderato
(PTHREAD_CREATE_JOINABLE)– Ritorno:
♦0: -> tutto OK♦!=0: un errore
40
Sincronizzazione thread• La sincronizzazione fra thread creante e thread
avviene in maniera simile ai processi
• Si utilizza la funzione pthread_join() (analogo della waitpid())
• Il thread invocante (o il processo) si blocca fino a quando un thread specificato da threadid termina
• Il thread invocante (o il processo) può leggere il codice di uscita
• A differenza dei processi, bisogna specificare esplicitamente che un thread sia “joinabile”
41
Sincronizzazione thread• Come si specifica la proprietà “joinable” sui
thread?
• Step 1: si dichiara una variabile “attributi” di tipo pthread_attr_t
• Step 2: si inizializza la variabile con la funzione pthread_attr_init()
• Step 3: si imposta l'attributo “detached” con la funzione pthread_attr_setdetachstate()
• Step 4: in un punto successivo, si rilasciano le risorse allocate con la funzione pthread_attr_destroy()
42
Sincronizzazione thread
43
Sincronizzazione thread• Signature: int pthread_join (pthread_t th, void
**thread_return);– Descrizione:
♦sospende l'esecuzione del thread invocante fino all'uscita del thread identificato da th
♦Se thread_return != NULL, scrive il codice di uscita nella cella puntata da thread_return
– Ingresso:♦un puntatore ad una struttura pthread_attr_t
– Ritorno:♦0: -> tutto OK♦!=0: un errore
44
Concorrenza thread• Per gestire l'accesso concorrente a variabili
condivise, si utilizza il costrutto dei semafori– Variabili mutex (MUTual Exclusion): interi posti
a 0 (risorsa libera) o 1 (risorsa occupata)pthread_mutex_t
– Ciascun mutex agisce come un lucchetto (lock) sugli altri thread che vogliono accedere alla risorsa
– Due stati:♦LOCKED: risorsa prenotata da un thread♦UNLOCKED: risorsa libera
– Impedisce le cosiddette corse critiche (accessi simultanei a variabili condivise, con indeterminatezza del risultato finale)
45
Concorrenza thread• Scenario tipico di utilizzo dei mutex
– Creazione ed inizializzazione di una variabile di tipo mutex
– Più thread provano a prenotare la risorsa, cercando di ottenere il lock sul mutex
– Un solo thread ci riesce (quello che arriva per primo) e prenota la risorsa per se
– Il thread modifica la risorsa in questione– Il thread rilascia la risorsa– Un altro thread acquisisce il lock sul mutex– Il processo si ripete– Il mutex viene distrutto
46
Concorrenza thread• Dichiarazione mutex: può avvenire in due modi
distinti– Dichiarazione statica:
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
– Dichiarazione dinamica:pthread_mutex_init()
47
Concorrenza thread• Signature: int pthread_mutex_init
(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);– Descrizione:
♦ Inizializza il mutex puntato da mutex con gli attributi puntati di mutexattr
♦ Il mutex è UNLOCKED (risorsa libera)– Ingresso:
♦un puntatore ad una struttura pthread_mutex_t
♦un puntatore ad una struttura pthread_mutex_attr_t
– Ritorno:♦Sempre 0
48
Concorrenza thread• Signature: int pthread_mutex_destroy
(pthread_mutex_t *mutex);– Descrizione:
♦Resetta lo stato del mutex puntato da mutex– Ingresso:
♦un puntatore ad una struttura pthread_mutex_t
– Ritorno:♦0: -> tutto OK♦!=0: il mutex è attualmente bloccato
49
Concorrenza thread• Signature: int pthread_mutex_lock
(pthread_mutex_t *mutex);– Descrizione:
♦ Prova ad acquisire un lock su mutex♦ Se mutex=UNLOCKED, lo acquisisce e torna♦ Se mutex=LOCKED, si blocca fino a quando la
risorsa non si libera
– Ingresso:♦ un puntatore ad una struttura pthread_mutex_t
– Ritorno:♦ 0: -> tutto OK♦ !=0: mutex non inizializzato o già bloccato dallo
stesso thread
50
Concorrenza thread• Signature: int pthread_mutex_trylock
(pthread_mutex_t *mutex);– Descrizione:
♦ Prova ad acquisire un lock su mutex♦ Se mutex=UNLOCKED, lo acquisisce e torna♦ Se mutex=LOCKED, ritorna e non si blocca
– Ingresso:♦ un puntatore ad una struttura pthread_mutex_t
– Ritorno:♦ 0: -> tutto OK♦ !=0: mutex non inizializzato, già bloccato dallo
stesso thread, già bloccato da un altro thread
51
Concorrenza thread• Signature: int pthread_mutex_unlock
(pthread_mutex_t *mutex);– Descrizione:
♦ Rilascia la risorsa associata al mutex♦ Reimposta il mutex ad UNLOCKED
– Ingresso:♦ un puntatore ad una struttura pthread_mutex_t
– Ritorno:♦ 0: -> tutto OK♦ !=0: mutex non inizializzato, già bloccato dallo
stesso thread, già bloccato da un altro thread
52
Variabili condizione• Le variabili condizione costituiscono un
ulteriore meccanismo per la sincronizzazione fra thread
• Idea: associare eventi al valore di alcune variabili– Una variabile assume un valore->scatta un
evento– Un'altra variabile, detta variabile condizione,
viene usata per segnalare l'evento– Callback: gestione asincrona di eventi tramite
invocazione di funzioni• Senza le variabili di condizione, un thread deve
continuamente controllare (poll) l'arrivo di eventi, sprecando inutilmente risorse di calcolo
53
Variabili condizione• Scenario tipico di utilizzo - variabili condizione• Tre thread:
– Thread Main: thread di controllo che schedula i thread di lavoro A e B
– Thread A: lavora fino ad un certo punto, poi si ferma in attesa di un evento
– Thread B: lavora fino ad un certo punto, poi scatena l'evento sul quale sta aspettando A
• Che funzioni eseguono i tre thread?
54
Variabili condizione• Thread Main:
– Dichiara ed inizializza (strutture) dati globali che necessitano di sincronizzazione
– Dichiara ed inizializza un oggetto di tipo “variabile condizione”
– Dichiara ed inizializza un mutex associato alla variabile condizione
– Crea i thread A e B– Join dei thread A e B
55
Variabili condizione• Thread A:
– Lavora fino a quando non si deve interrompere, in attesa che una condizione si verifichi
– Acquisisce il lock sul mutex– Si blocca (pthread_cond_wait()) fino a quando
non si verifica l'evento, segnalato da un altro thread (Thread B)
– pthread_cond_wait() sblocca automaticamente il mutex, che può essere utilizzato dall'altro thread per acquisire uso esclusivo sulla variabile che rappresenta l'evento
– Quando arriva il segnale, Thread A si sveglia ed il mutex viene di nuovo assegnato a lui
– Thread A rilascia esplicitamente il mutex
56
Variabili condizione• Thread B:
– Lavora– Acquisisce il lock sul mutex– Cambia il valore della variabile su cui è bloccato
Thread A– Se il valore della variabile è tale da scatenare un
evento, segnala Thread A tramite una variabile condizione
– Rilascia esplicitamente il mutex
57
Variabili condizione• Rappresentate dal tipo di dato opaco
pthread_cond_t• Devono essere inizializzate prima di poter
essere utilizzate• Possono specificare dei propri attributi• L'inizializzazione avviene in due modi distinti:
– Inizializzazione statica:pthread_cond_t myconvar = PTHREAD_COND_INITIALIZER;
– Inizializzazione dinamica:pthread_cond_init()
58
Variabili condizione• Signature: int pthread_cond_init
(pthread_cond_t *cond, const pthread_condattr_t *cond_attr);– Descrizione:
♦ Inizializza la variabile condizione cond utilizzando gli attributi cond_attr (NULL per default)
– Ingresso:♦un puntatore ad una struttura
pthread_cond_t♦un puntatore ad una struttura
pthread_condattr_t– Ritorno:
♦Sempre 0
59
Variabili condizione• Signature: int pthread_cond_destroy
(pthread_cond_t *cond);– Descrizione:
♦Resetta una variabile condizione cond, rilasciando le risorse che potrebbe avere allocato
– Ingresso:♦un puntatore ad una struttura
pthread_cond_t– Ritorno:
♦0: -> tutto OK♦!=0: la variabile condizione è attualmente
utilizzata da un qualche thread
60
Variabili condizione• Signature: int pthread_condattr_init
(pthread_condattr_t *attr);– Descrizione: inizializza una struttura
pthread_condattr_t– Ingresso:
♦un puntatore ad una struttura pthread_condattr_t
– Ritorno:♦Sempre 0
61
Variabili condizione• Signature: int pthread_condattr_init
(pthread_condattr_t *attr);– Descrizione: inizializza una struttura
pthread_condattr_t– Ingresso:
♦un puntatore ad una struttura pthread_condattr_t
– Ritorno:♦Sempre 0
62
Variabili condizione• Signature: int pthread_condattr_destroy
(pthread_condattr_t *attr);– Descrizione: resetta una struttura
pthread_condattr_t– Ingresso:
♦un puntatore ad una struttura pthread_condattr_t
– Ritorno:♦Sempre 0
63
Variabili condizione• Signature: int pthread_cond_wait
(pthread_cond_t *cond, pthread_mutex_t *mutex);– Descrizione:
♦Blocca il thread invocante fino a quando non viene segnalata la condizione cond
♦Deve essere invocata con mutex bloccato (altrimenti un thread potrebbe segnalare la condizione prima che un altro possa ascoltarla); il mutex viene automaticamente sbloccato al termine della chiamata
♦Quando si verifica la condizione, il thread viene svegliato e mutex viene acquisito di nuovo (ricordatevi di rilasciarlo!)
64
Variabili condizione• Signature: int pthread_cond_wait
(pthread_cond_t *cond, pthread_mutex_t *mutex);– Ingresso:
♦Un puntatore alla struttura pthread_cont_t che rappresenta la variabile condizione su cui aspettare
♦Un puntatore alla struttura pthread_mutex_t che rappresenta il mutex associato alla variabile condizione
– Ritorno:♦Sempre 0
65
Variabili condizione• Signature: int pthread_cond_signal
(pthread_cond_t *cond);– Descrizione:
♦Segnala (risveglia) un altro thread in seguito al verificarsi di una data condizione
♦Più thread possono aspettare una data condizione; pthread_cond_signal() ne risveglia solamente uno
– Ingresso:♦Un puntatore alla struttura pthread_cont_t
che rappresenta la variabile condizione su cui aspettare
– Ritorno:♦Sempre 0
66
Variabili condizione• Signature: int pthread_cond_broadcast
(pthread_cond_t *cond);– Descrizione:
♦Segnala (risveglia) un insieme di thread in seguito al verificarsi di una data condizione
♦Più thread possono aspettare una data condizione; pthread_cond_broadcast() li risveglia tutti
– Ingresso:♦Un puntatore alla struttura pthread_cont_t
che rappresenta la variabile condizione su cui aspettare
– Ritorno:♦Sempre 0