[Avanti]  [Indietro]  [Su]  

7.3.3 Gli stream e i thread

Gli stream possono essere usati in applicazioni multi-thread allo stesso modo in cui sono usati nelle applicazioni normali, ma si deve essere consapevoli delle possibili complicazioni anche quando non si usano i thread, dato che l'implementazione delle librerie è influenzata pesantemente dalle richieste necessarie per garantirne l'uso con i thread.

Lo standard POSIX richiede che le operazioni sui file siano atomiche rispetto ai thread, per questo le operazioni sui buffer effettuate dalle funzioni di libreria durante la lettura e la scrittura di uno stream devono essere opportunamente protette (in quanto il sistema assicura l'atomicità solo per le system call). Questo viene fatto associando ad ogni stream un opportuno blocco che deve essere implicitamente acquisito prima dell'esecuzione di qualunque operazione.

Ci sono comunque situazioni in cui questo non basta, come quando un thread necessita di compiere più di una operazione sullo stream atomicamente, per questo motivo le librerie provvedono anche delle funzioni flockfile, ftrylockfile e funlockfile, che permettono la gestione esplicita dei blocchi sugli stream; esse sono disponibili definendo _POSIX_THREAD_SAFE_FUNCTIONS ed i loro prototipi sono:

con queste funzioni diventa possibile acquisire un blocco ed eseguire tutte le operazioni volute, per poi rilasciarlo.

Ma, vista la complessità delle strutture di dati coinvolte, le operazioni di blocco non sono del tutto indolori, e quando il locking dello stream non è necessario (come in tutti i programmi che non usano i thread), tutta la procedura può comportare dei costi pesanti in termini di prestazioni. Per questo motivo abbiamo visto come alle usuali funzioni di I/O non formattato siano associate delle versioni _unlocked (alcune previste dallo stesso standard POSIX, altre aggiunte come estensioni dalle glibc) che possono essere usate quando il locking non serve12 con prestazioni molto più elevate, dato che spesso queste versioni (come accade per getc e putc) sono realizzate come macro.

La sostituzione di tutte le funzioni di I/O con le relative versioni _unlocked in un programma che non usa i thread è però un lavoro abbastanza noioso; per questo motivo le glibc forniscono al programmatore pigro un'altra via13 da poter utilizzare per disabilitare in blocco il locking degli stream: l'uso della funzione __fsetlocking, il cui prototipo è:

Restituisce lo stato di locking interno dello stream con uno dei valori FSETLOCKING_INTERNAL o FSETLOCKING_BYCALLER.

La funzione imposta o legge lo stato della modalità di operazione di uno stream nei confronti del locking a seconda del valore specificato con type, che può essere uno dei seguenti:


[Avanti]  [Indietro]  [Su]  
© 2000-2003 Simone Piccardi
Pubblicazione web curata da Mirko Maischberger