Provided by: manpages-pl_4.26.0-1_all 

NAZWA
attributes - pojęcia bezpieczeństwa POSIX
OPIS
Uwaga: tekst niniejszej strony podręcznika systemowego powstał w oparciu o materiał z rozdziału „POSIX
Safety Concepts” podręcznika biblioteki GNU C. Więcej szczegółów na temat poniższych tematów można
znaleźć tamże.
Różne strony podręcznika systemowego zawierają rozdział ATRYBUTY opisujący bezpieczeństwa wywoływania
funkcji w różnych sytuacjach. Niniejszy rozdział opisuje funkcje z następującymi oznaczeniami
bezpieczeństwa:
MT-bezpieczne
Funkcje MT-bezpieczne, MT-Safe lub wątkowo-bezpieczne można bezpiecznie wywołać w obecności innych
wątków. Cząstka MT w nazwie oznacza wielowątkowość (ang. Multi Thread).
Bycie MT-bezpieczną nie oznacza, że funkcja jest niepodzielna, ani że używa jakichś mechanizmów
synchronizacji pamięci, udostępnianych przez POSIX użytkownikom. Możliwe jest nawet, że wywołania
kolejnych funkcji MT-bezpiecznych nie da w efekcie kombinacji MT-bezpiecznej. Przykładowo, jeśli
istnieje wątek wywołujący dwie funkcje MT-bezpieczne jedna po drugiej, nie gwarantuje to
zachowania równoważnego niepodzielnemu wykonaniu kombinacji obu funkcji, ponieważ współbieżne
wywołania w różnych wątkach mogą ze sobą oddziaływać w destrukcyjny sposób.
Optymalizacje całych programów, które mogą doprowadzić do wyodrębnienia funkcji jako podprogramu
(funkcji otwartej) na przestrzeni interfejsów biblioteki, mogą doprowadzić do niebezpiecznej
zmiany kolejności, dlatego nie zaleca się dokonywania takiego wyodrębniania na przestrzeni
interfejsu biblioteki GNU C. Udokumentowany status MT-bezpieczny nie jest gwarantowany przy
optymalizacji całych programów. Jednak funkcje zdefiniowane w widocznych dla użytkownika
nagłówkach, są zaprojektowane jako bezpieczne do wyodrębniania.
MT-niebezpieczne
Funkcje MT-niebezpieczne lub MT-Unsafe nie są bezpieczne do wywołania w programach wielowątkowych.
Inne słowa kluczowe pojawiające się w uwagach nt. bezpieczeństwa zdefiniowano w kolejnych rozdziałach.
Funkcjonalności warunkowo bezpieczne
Dla niektórych funkcjonalności czyniących funkcje niebezpiecznymi do wywołania w pewnych sytuacjach,
znane są sposoby ominięcia kłopotów z bezpieczeństwem, nie wymagające całkowitej rezygnacji z ich
wywoływania. Poniższe słowa kluczowe odnoszą się do takich funkcjonalności i każda z definicji wskazuje,
jak należy ograniczyć cały program, aby uniknąć problemu z bezpieczeństwem wskazanych danym słowem
kluczowym. Jedynie po zaobserwowaniu i odniesieniu się do powodów, które czynią funkcję niebezpieczną, za
pomocą nałożenia udokumentowanych ograniczeń, funkcja staje się bezpieczna do wywołania w danym
kontekście.
init Funkcje oznaczone jako init w kontekście problemów bezpieczeństwa wątkowego, przeprowadzają przy
pierwszym wywołaniu inicjalizację, która jest MT-niebezpieczna.
Wywołanie takiej funkcji przynajmniej raz w trybie pojedynczego wątku, usuwa ten konkretny powód
do uznania tej funkcji jako MT-niebezpiecznej. Jeśli nie występują inne powody, to funkcję można
bezpiecznie wywoływać po uruchomieniu innych wątków.
race Funkcje oznaczone jak race w kontekście problemów bezpieczeństwa wątkowego działają na obiektach w
sposób, który może powodować wyścig do danych lub inne formy destrukcyjnej interferencji przy
współbieżnym wykonaniu. W niektórych przypadkach te obiekty są przekazywane do funkcji przez
użytkowników; w innych są one używane przez funkcje do zwrócenia wartości użytkownikom; w jeszcze
innych nie są nawet ujawniane użytkownikom.
const Funkcje oznaczone jako const w kontekście problemów bezpieczeństwa wątkowego, modyfikują w sposób
nieatomowy obiekty wewnętrzne, które mogą być raczej rozważane jako stałe, ponieważ znaczna część
biblioteki GNU C korzysta z nich bez synchronizacji. W przeciwieństwie do race, które powoduje
uznanie za MT-niebezpieczną zarówno odczytujących jak i zapisujących obiekty wewnętrzne, to
oznaczenie odnosi się wyłącznie do zapisujących. Zapisujący pozostają MT-niebezpieczni przy
wywołaniu, lecz obowiązkowa później stałość obiektów, które modyfikują, umożliwia uznanie
odczytujących za MT-bezpiecznych (o ile nie pozostają inne powody do uznania ich za
niebezpiecznych), ponieważ brak synchronizacji nie jest problemem, gdy obiekty są faktycznie
stałe.
Identyfikator, który występuje po oznaczeniu const pojawi się jako adnotacja bezpieczeństwa przy
odczytujących. Programy, które chcą przeciwdziałać temu problemowi bezpieczeństwa, jednak tak aby
móc wywołać zapisujących, mogą użyć nierekurencyjnej blokady odczytu i zapisu powiązanej z
identyfikatorem i chronić wszystkie wywołania do funkcji oznaczonej jako const, po której
następuje identyfikator blokady zapisu oraz wszystkie wywołania do funkcji oznaczonej samym
identyfikatorem za pomocą blokady odczytu.
sig Funkcje oznaczone jako sig w kontekście problemów bezpieczeństwa wątkowego mogą tymczasowo
instalować procedurę obsługi sygnału do celów wewnętrznych, która może interferować z innymi
użyciami sygnału, wymienionymi po dwukropku.
Temu problemowi bezpieczeństwa można przeciwdziałać, upewniając się, że w trakcie wywołania nie
dojdzie do innego użycia sygnału. Zalecane jest: utrzymywanie nierekurencyjnej blokady mutex
(wzajemnego wykluczania) podczas wywoływania wszystkich funkcji używających tego samego sygnału
tymczasowego; blokowanie tego sygnału przed wywołaniem i późniejsze resetowanie jego procedury
obsługi.
term Funkcje oznaczone jako term w kontekście problemów bezpieczeństwa wątkowego mogą zmieniać
ustawienia terminala w zalecany sposób, głównie: wywoływać tcgetattr(3), modyfikować niektóre
znaczniki (flagi) i później wywoływać tcsetattr(3), co otwiera okno, w którym zmiany wykonane
przez inne wątki są tracone. Z tego względu funkcje oznaczone jako term są MT-niebezpieczne.
Zaleca się dlatego aplikacjom używającym terminala unikać równoczesnej i wielobieżnej interakcji z
terminalem, nie używając mogących się tak zachowywać procedur obsługi sygnału lub sygnałów
blokujących i utrzymywać blokadę przy ponownym wywoływaniu tych funkcji i interakcji z terminalem.
Blokady tej powinno się używać również do wzajemnego wykluczania w przypadku funkcji oznaczonych
jako race:tcattr(fd), gdzie fd jest deskryptorem pliku kontrolującego terminala. Wywołujący może
użyć następujących blokad wzajemnego wykluczania (mutex): pojedynczej (dla ułatwienia) albo po
jednej na terminal, nawet gdy są one opisane różnymi deskryptorami pliku.
Dodatkowe uwagi dotyczące bezpieczeństwa
Do funkcji mogą być dołączone dodatkowe słowa kluczowe wskazujące funkcjonalności, które co prawda nie
czynią funkcji niebezpiecznej do wywołania, ale powinny być wzięte pod uwagę w określonych klasach
programów:
locale Funkcje z adnotacją locale w kontekście problemów bezpieczeństwa wątkowego odczytują z obiektu
locale (tłumaczenia) bez jakiejkolwiek formy synchronizacji. Funkcje z adnotacją locale wywoływane
równolegle ze zmianą locale mogą zachowywać się w sposób nieodnoszący się do żadnych z aktywnych
locale podczas ich wykonania, lecz z nieprzewidywalną ich mieszanką.
Funkcje te nie są jednak oznaczane jako MT-niebezpieczne. To funkcje modyfikujące obiekt locale są
oznaczane uwagą const:locale i są uważane za niebezpieczne. Z tego powodu, funkcje modyfikujące
nie powinny być wywoływane, gdy działa kilka wątków lub włączone są sygnały asynchroniczne. W tych
kontekstach locale mogą być rozważane jako efektywnie stałe, co czyni omawiane w powyższym
akapicie funkcje bezpiecznymi.
env Funkcje oznaczone jako env w kontekście problemów bezpieczeństwa wątkowego uzyskują dostęp do
środowiska za pomocą getenv(3) lub podobnego, bez żadnej ochrony zapewniającej bezpieczeństwo w
obecności równoległych modyfikacji.
Funkcje te nie są jednak oznaczane jako MT-niebezpieczne. To funkcje modyfikujące środowisko są
oznaczane uwagą const:env i są uważane za niebezpieczne. Z tego powodu, funkcje modyfikujące nie
powinny być wywoływane, gdy działa kilka wątków lub włączone są sygnały asynchroniczne. W tych
kontekstach środowisko może być rozważane jako efektywnie stałe, co czyni omawiane w powyższym
akapicie funkcje bezpiecznymi.
hostid Funkcje oznaczone jako hostid w kontekście problemów bezpieczeństwa wątkowego odczytują z
systemowych struktur danych identyfikator stacji („host id”). Te struktury danych zwykle nie mogą
być modyfikowane w sposób niepodzielny. Ze względu na założenie, że identyfikator stacji nie
powinien się zmieniać, funkcje odczytujące go (gethostid(3)) są uważane za bezpieczne, natomiast
funkcje go modyfikujące (sethostid(3)) są oznaczane jako const:hostid wskazując, że ich wywołanie
może wymagać szczególnej uwagi. W tym konkretnym przypadku, szczególna uwagę należy zwrócić na
koordynację na poziomie systemu (a nie jedynie wewnątrzprocesową).
sigintr
Funkcje oznaczone jako sigintr w kontekście problemów bezpieczeństwa wątkowego uzyskują dostęp do
wewnętrznej struktury danych _sigintr biblioteki GNU C, bez żadnej ochrony zapewniającej
bezpieczeństwo w momencie równoległej modyfikacji.
Funkcje te nie są jednak oznaczane jako MT-niebezpieczne. To funkcje modyfikujące struktury danych
są oznaczane uwagą const:sigintr i są uważane za niebezpieczne. Z tego powodu, funkcje
modyfikujące nie powinny być wywoływane, gdy działa kilka wątków lub włączone są sygnały
asynchroniczne. W tych kontekstach struktury danych mogą być rozważane jako efektywnie stałe, co
czyni omawiane w powyższym akapicie funkcje bezpiecznymi.
cwd Funkcje oznaczone jako cwd w kontekście problemów bezpieczeństwa wątkowego mogą tymczasowo
zmieniać bieżący katalog roboczy podczas wykonania, co może spowodować ustalanie ścieżek
względnych w sposób nieoczekiwany dla innych wątków lub przy procedurach obsługi odwoływania lub
asynchronicznych sygnałach.
Nie jest to wystarczający powód do oznaczania funkcji z taką adnotacją jako MT-niebezpiecznej,
lecz gdy zachowanie to jest opcjonalne (np. nftw(3) z FTW_CHDIR), unikanie takiej opcji może być
dobrą alternatywą do używania pełnych ścieżek lub wywołań systemowych odnoszących się do
deskryptorów pliku (np. openat(2)).
:identyfikator
Po adnotacjach może czasem wystąpić identyfikator, który ma pogrupować funkcje, które np. uzyskują
dostęp do struktur danych w niebezpieczny sposób, jak w przypadku race i const lub udostępniać
szczegółowe informacje, takie jak nazwa sygnału w funkcji oznaczonej jako sig. Przewiduje się, że
może to w przyszłości dotyczyć również lock i corrupt.
W większości przypadku identyfikator wymieni zestaw funkcji, ale czasami może nazwać obiekty
globalne, argumenty funkcji lub powiązane z nimi identyfikowalne właściwości lub fragmenty
logiczne. Stosowania notacja to np. :buf(arg) aby wskazać bufor powiązany z argumentem arg lub
:tcattr(fd) aby wskazać atrybuty terminala deskryptora pliku fd.
Najczęstszym zastosowanie identyfikatorów jest udostępnienie logicznych grup funkcji i argumentów,
które muszą być chronione przez te same mechanizmy synchronizacji, aby zapewnić bezpieczne
operowanie w danym kontekście.
/warunek
Część uwag bezpieczeństwa może być warunkowa co oznacza, że mają zastosowanie tylko gdy prawdziwe
jest wyrażenie warunkowe dotyczące argumentów, zmiennych globalnych albo nawet wartości jądra. Na
przykład /!ps i /one_per_line wskazują, że wcześniejsza uwaga ma zastosowanie tylko, gdy
argumentem ps jest NULL, albo zmienna globalna one_per_line jest niezerowa.
Jeśli wszystkie uwagi czyniące funkcję niebezpieczną są opatrzone takimi warunkami i żaden z
wskazanych warunków nie jest spełniony, to funkcja może być uważana za bezpieczną.
ZOBACZ TAKŻE
pthreads(7), signal-safety(7)
TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ
ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-
list@lists.sourceforge.net.
Linux man-pages 6.9.1 2 maja 2024 r. attributes(7)