attributes - concepte de siguranță POSIX
Notă: textul acestei pagini de manual se
bazează pe materialul preluat din secțiunea „POSIX
Safety Concepts” a manualului GNU C Library. Detalii suplimentare
despre subiectele descrise aici pot fi găsite în acel
manual.
Diverse pagini de manual ale funcțiilor includ o
secțiune ATRIBUTE care descrie siguranța apelării
funcției în diverse contexte. Această secțiune
adnotează funcțiile cu următoarele marcaje de
siguranță:
- MT-Safe
- Funcțiile MT-Safe sau Thread-Safe pot fi apelate în
siguranță în prezența altor fire de
execuție. MT, în MT-Safe, înseamnă Multi
Thread. (multiple fire de execuție)
- A fi MT-Safe nu înseamnă că o funcție este
atomică și nici că utilizează vreunul dintre
mecanismele de sincronizare a memoriei pe care POSIX le expune
utilizatorilor. Este chiar posibil ca apelarea funcțiilor MT-Safe
în succesiune să nu producă o combinație
MT-Safe. De exemplu, apelarea de către un fir de execuție a
două funcții MT-Safe una imediat după alta nu
garantează un comportament echivalent cu execuția
atomică a unei combinații a ambelor funcții, deoarece
apelurile simultane în alte fire de execuție pot interfera
într-un mod distructiv.
- Optimizările întregului program care ar putea include
funcții în interfețe de bibliotecă pot expune
o reordonare nesigură și, prin urmare, nu se
recomandă includerea în interfața bibliotecii GNU C.
Statutul MT-Safety documentat nu este garantat în cazul
optimizării întregului program. Cu toate acestea,
funcțiile definite în antetele vizibile pentru utilizator
sunt proiectate să fie sigure pentru „inlining”.
- MT-Unsafe
- Funcțiile MT-Unsafe nu pot fi apelate în
siguranță în programele multithreaded (executate
folosind mai multe fire).
Alte cuvinte-cheie care apar în notele de
siguranță sunt definite în secțiunile
următoare.
Pentru unele caracteristici care fac ca apelarea funcțiilor
să fie nesigură în anumite contexte, există
modalități cunoscute de a evita problema
securității, altele decât abținerea
totală de la apelarea funcției. Cuvintele-cheie care
urmează se referă la astfel de caracteristici, iar fiecare
dintre definițiile lor indică modul în care
întregul program trebuie să fie constrâns pentru a
elimina problema de securitate indicată de cuvântul-cheie.
Numai atunci când toate motivele care fac o funcție
nesigură sunt observate și abordate, prin aplicarea
constrângerilor documentate, funcția devine sigură
pentru a fi apelată într-un context.
- init
- Funcțiile marcate cu init ca o caracteristică
MT-Unsafe efectuează inițializarea MT-Unsafe atunci
când sunt apelate pentru prima dată.
- Apelarea unei astfel de funcții cel puțin o dată
în modul single-threaded (un singur fir de execuție)
elimină această cauză specifică pentru care
funcția este considerată MT-Unsafe. Dacă nu
rămâne nicio altă cauză, funcția poate
fi apelată în siguranță după pornirea
altor fire de execuție.
- race
- Funcțiile adnotate cu race ca o problemă de
siguranță MT operează asupra obiectelor în
moduri care pot cauza curse de date sau forme similare de
interferență distructivă în afara
execuției simultane. În unele cazuri, obiectele sunt
transmise funcțiilor de către utilizatori; în altele,
acestea sunt utilizate de către funcții pentru a returna
valori utilizatorilor; în altele, acestea nici măcar nu sunt
expuse utilizatorilor.
- const
- Funcțiile marcate cu const ca o problemă de MT-Safety
modifică non-atomic obiecte interne care sunt mai bine considerate
constante, deoarece o parte substanțială a bibliotecii GNU C
le accesează fără sincronizare. Spre deosebire de
race, care face ca atât cititorii, cât și
scriitorii de obiecte interne să fie considerați MT-Unsafe,
acest marcaj este aplicat doar scriitorilor. Scriitorii
rămân MT-Unsafe la apelare, dar constanța obligatorie
a obiectelor pe care le modifică permite cititorilor să fie
considerați MT-Safe (atât timp cât nu există
alte motive pentru care să fie nesiguri), deoarece lipsa
sincronizării nu este o problemă atunci când
obiectele sunt efectiv constante.
- Identificatorul care urmează marcajul const va apărea
de la sine ca o notă de siguranță în
cititoare. Programele care doresc să ocolească
această problemă de siguranță, astfel
încât să apeleze scriitorii, pot utiliza un blocaj de
citire-scriere non-recursiv asociat identificatorului și să
protejeze apelurile all către funcțiile marcate cu
const urmate de identificator cu un blocaj de scriere și
apelurile all către funcțiile marcate cu
identificatorul de la sine cu un blocaj de citire.
- sig
- Funcțiile marcate cu sig ca o problemă de
siguranță MT pot instala temporar un gestionar de semnal
în scopuri interne, care poate interfera cu alte utilizări
ale semnalului, identificat după două puncte (:).
- Această problemă de siguranță poate fi
rezolvată prin asigurarea faptului că nu vor avea loc alte
utilizări ale semnalului pe durata apelului. Se recomandă
menținerea unui mutex non-recursiv în timpul apelării
tuturor funcțiilor care utilizează același semnal
temporar; blocarea semnalului respectiv înainte de apel și
reinițializarea gestionarului acestuia după apel.
- term
- Funcțiile marcate cu term ca fiind o problemă de
MT-Safety pot modifica parametrii terminalului în modul recomandat,
și anume: apelează tcgetattr(3), modifică
unele opțiuni și apoi apelează tcsetattr(3),
ceea ce creează o fereastră în care
modificările efectuate de alte fire se pierd. Astfel,
funcțiile marcate cu term sunt MT-Unsafe.
- Prin urmare, este recomandabil ca aplicațiile care
utilizează terminalul să evite interacțiunile
concurente și reentrante cu acesta, neutilizându-l în
gestionarii de semnale sau blocând semnalele care l-ar putea
utiliza și deținând un blocaj în timp ce
apelează aceste funcții și
interacționează cu terminalul. Această blocare ar
trebui, de asemenea, utilizată pentru excluderea reciprocă
cu funcții marcate cu race:tcattr(fd), unde fd este
un descriptor de fișier pentru terminalul de control. Apelantul
poate utiliza un singur mutex pentru simplificare sau poate utiliza un
mutex pentru fiecare terminal, chiar dacă se face referire la
acesta prin descriptori de fișier diferiți.
Funcțiilor li se pot atașa cuvinte-cheie
suplimentare, indicând caracteristici care nu fac ca apelarea unei
funcții să fie nesigură, dar care ar putea fi luate
în considerare în anumite clase de programe:
- locale
- Funcțiile notate cu locale ca o problemă de
siguranță MT citesc din obiectul de configurare
regională fără nicio formă de sincronizare.
Funcțiile adnotate cu locale apelate concomitent cu
modificările configurării regionale se pot comporta
în moduri care nu corespund niciuneia dintre configurațiile
regionale active în timpul execuției lor, ci unui amestec
imprevizibil al acestora.
- Cu toate acestea, nu marcăm aceste funcții ca MT-Unsafe,
deoarece funcțiile care modifică obiectul de configurare
regională sunt marcate cu const:locale și considerate
nesigure. Fiind nesigure, acestea din urmă nu trebuie să fie
apelate atunci când rulează mai multe fire de
execuție sau când sunt activate semnale asincrone și,
astfel, configurările regionale pot fi considerate efectiv
constante în aceste contexte, ceea ce le face sigure.
- env
- Funcțiile marcate cu env ca o problemă de
siguranță MT accesează mediul cu getenv(3) sau
similar, fără nicio protecție pentru a asigura
siguranța în prezența modificărilor
simultane.
- Cu toate acestea, nu marcăm aceste funcții ca MT-Unsafe,
deoarece funcțiile care modifică mediul sunt toate marcate
cu const:env și considerate nesigure. Fiind nesigure,
acestea din urmă nu trebuie să fie apelate atunci
când rulează mai multe fire de execuție sau
când sunt activate semnale asincrone, astfel încât
mediul poate fi considerat efectiv constant în aceste contexte,
ceea ce le face sigure.
- hostid
- Funcția marcată cu hostid ca o problemă de
siguranță MT citește din structurile de date la nivel
de sistem care conțin „ID-ul de gazdă” al
mașinii. În general, aceste structuri de date nu pot fi
modificate atomic. Deoarece se preconizează că „ID-ul
gazdei” nu se va modifica în mod normal, funcția care
citește din acesta (gethostid(3)) este considerată
sigură, în timp ce funcția care îl
modifică (sethostid(3)) este marcată cu
const:hostid, indicând faptul că ar putea necesita o
atenție specială dacă va fi apelată. În
acest caz specific, grija specială înseamnă
coordonare la nivelul întregului sistem (nu doar în
interiorul procesului).
- sigintr
- Funcțiile marcate cu sigintr ca o problemă de
siguranță MT accesează structura internă de
date _sigintr a Bibliotecii GNU C fără nicio
protecție pentru a asigura siguranța în
prezența modificărilor simultane.
- Cu toate acestea, nu marcăm aceste funcții ca MT-Unsafe,
deoarece funcțiile care modifică această
structură de date sunt toate marcate cu const:sigintr
și considerate nesigure. Fiind nesigure, acestea din urmă nu
trebuie să fie apelate atunci când rulează mai multe
fire de execuție sau când sunt activate semnale asincrone,
astfel încât structura de date poate fi considerată
efectiv constantă în aceste contexte, ceea ce le face pe
primele sigure.
- cwd
- Funcțiile marcate cu cwd ca o problemă de
siguranță MT pot modifica temporar directorul curent de
lucru în timpul execuției lor, ceea ce poate determina
rezolvarea în moduri neașteptate a numelor de rute relative
în alte fire de execuție sau în cadrul gestionarilor
asincroni de semnal sau de anulare.
- Acesta nu este un motiv suficient pentru a marca funcțiile astfel
marcate ca MT-Unsafe, dar atunci când acest comportament este
opțional (de exemplu, nftw(3) cu FTW_CHDIR), evitarea
opțiunii poate fi o alternativă bună la utilizarea
numelor de rută complete sau a apelurilor de sistem relative la
descriptorul de fișier (de exemplu, openat(2)).
- :identifier
- Adnotările pot fi uneori urmate de identificatori, destinați
să grupeze mai multe funcții care, de exemplu,
accesează structurile de date într-un mod nesigur, ca
în race și const, sau să furnizeze
informații mai specifice, cum ar fi numirea unui semnal
într-o funcție marcată cu sig. Se
preconizează că, în viitor, aceasta poate fi
aplicată și la lock și corrupt.
- În majoritatea cazurilor, identificatorul va numi un set de
funcții, dar poate numi obiecte globale sau argumente de
funcții, sau proprietăți identificabile sau
componente logice asociate cu acestea, cu o notație precum, de
exemplu, :buf(arg) pentru a desemna un tampon asociat cu argumentul
arg, sau :tcattr(fd) pentru a desemna atributele terminale
ale unui descriptor de fișier fd.
- Cea mai frecventă utilizare a identificatorilor este de a furniza
grupuri logice de funcții și argumente care trebuie
să fie protejate de aceeași primitivă de sincronizare
pentru a asigura funcționarea sigură într-un anumit
context.
- /condition
- Unele adnotări de siguranță pot fi
condiționate, în sensul că se aplică numai
dacă o expresie booleană care implică argumente,
variabile globale sau chiar nucleul subiacent este evaluată la
adevărat (true). De exemplu, /!ps și
/one_per_line indică faptul că marcajul precedent se
aplică numai atunci când argumentul ps este NULL sau
variabila globală one_per_line este diferită de
zero.
- Atunci când toate marcajele care fac o funcție
nesigură sunt „împodobite” cu astfel de
condiții și niciuna dintre condițiile
menționate nu se aplică, atunci funcția poate fi
considerată sigură.
Traducerea în limba română a acestui manual a
fost făcută de Remus-Gabriel Chelu
<remusgabriel.chelu@disroot.org>
Această traducere este documentație gratuită;
citiți
Licența
publică generală GNU Versiunea 3 sau o versiune
ulterioară cu privire la condiții privind drepturile de autor.
NU se asumă NICIO RESPONSABILITATE.
Dacă găsiți erori în traducerea
acestui manual, vă rugăm să trimiteți un e-mail
la
translation-team-ro@lists.sourceforge.net.