Czy malloc jest bezpieczny?

Czy funkcja malloc() jest ponownie włączona?

Author: einpoklum, 2009-05-13

11 answers

Czytałem gdzieś, że jeśli skompilujesz z-pthread, malloc stanie się bezpieczny dla wątku. Jestem prawie pewien, że jego implementacja jest zależna, ponieważ malloc jest ANSI C, a wątki nie.

Jeśli mówimy o gcc:

Skompilować i połączyć z-pthread i malloc () będzie bezpieczny dla wątków, na x86 i AMD64.

Http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/2431a99b9bdcef11/ea800579e40f7fa4

Kolejna opinia, więcej wnikliwe

{malloc, calloc, realloc, free, posix_memalign} glibc-2.2+ to thread safe

Http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2005-07/0323.html

 38
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-05 01:43:12

Pytanie: czy malloc jest reentrant?
Odpowiedź: Nie, Nie jest. Oto jedna z definicji tego, co sprawia, że rutyna jest reentrant .

Żadna z popularnych wersji malloc nie pozwala na ponowne wprowadzenie go (np. z obsługi sygnału). Zauważ, że funkcja reentrant może nie używać blokad, a prawie wszystkie istniejące wersje malloc używają blokad (co czyni je bezpiecznymi dla wątku) lub zmiennych globalnych/statycznych(co czyni je niebezpiecznymi dla wątku i non-reentrant).

Wszystkie odpowiedzi tak dalsza odpowiedź " czy malloc jest bezpieczny?", co jest zupełnie innym pytaniem. Aby odpowiedzieć na to pytanie odpowiedź brzmi to zależy od biblioteki uruchomieniowej i ewentualnie od używanych flag kompilatora. Na każdym nowoczesnym Uniksie, domyślnie dostaniesz malloc bezpieczny dla wątków. W systemie Windows użyj /MT, /MTd, /MD lub /MDd flagi, aby uzyskać bibliotekę runtime safe thread.

 91
Author: Employed Russian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-10 15:16:05

Oto fragment z malloc.c glibc:

Thread-safety: thread-safe, chyba że zdefiniowano NO_THREADS

Zakładając, że NO_THREADS nie jest domyślnie zdefiniowane, malloc jest bezpieczny dla wątków przynajmniej w Linuksie.

 8
Author: shahkhas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-20 14:50:36

To dość stare pytanie i chcę nadać świeżości zgodnie z aktualnym stanem rzeczy.

Tak, obecnie {[0] } jest bezpieczny dla wątków.

Z podręcznika referencyjnego biblioteki GNU C z glibc-2.20 [released 2014-09-07]:

void * malloc (size_t size)

Preliminary: MT-Safe | ...

... 1.2.2.1 koncepcje bezpieczeństwa POSIX:

... MT-Safe lub Thread-Safe funkcje są bezpieczne do wywołania w obecności innych wątków. MT, w MT-Safe, oznacza Multi Thread.

Bycie MT-bezpiecznym nie oznacza, że funkcja jest atomowa, ani że używa każdy z mechanizmów synchronizacji pamięci, jakie POSIX udostępnia użytkownikom. Jest nawet możliwe, że wywołanie funkcji MT-Safe w sekwencji nie nie daje kombinacji MT-Safe. Na przykład wywołanie wątku dwie funkcje MT-Safe jedna po drugiej nie gwarantuje zachowanie równoważne wykonaniu atomowym kombinacji obu funkcji, ponieważ równoczesne wywołania w innych wątkach mogą zakłócać destrukcyjny sposób.

Optymalizacje całego programu, które mogą wbudowywać funkcje w całej bibliotece interfejsy mogą narażać na niebezpieczne zmiany kolejności, a więc wykonywanie inliningu interfejs biblioteki GNU C nie jest zalecany. Udokumentowane MT-stan bezpieczeństwa nie jest gwarantowany pod optymalizacją programu. Jednak funkcje zdefiniowane w widocznych przez użytkownika nagłówkach mają być bezpieczny do wkładania.

 8
Author: likern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-10 13:22:41

Tak, pod POSIX.1-2008 malloc jest bezpieczny dla nici.

2.9.1 Wątek-Bezpieczeństwo

Wszystkie funkcje zdefiniowane przez ten wolumin POSIX.1-2008 musi być bezpieczny dla wątku, z tym wyjątkiem, że następujące funkcje1 nie muszą być bezpieczne dla wątku.

[Lista funkcji, które nie zawierają malloc]

 5
Author: Tanz87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-04 01:30:01

Jeśli pracujesz z GLIBC, odpowiedź brzmi: tak, ale.

Konkretnie tak, ale proszę pamiętać, że podczas gdy malloc i free są bezpieczne dla wątków, funkcje debugowania nie są.

W szczególności, niezwykle użyteczne funkcje mtrace(), mcheck() i mprobe () nie są bezpieczne dla wątków. W jednej z najkrótszych, najprostszych odpowiedzi, jakie kiedykolwiek zobaczycie z projektu GNU, jest to wyjaśnione tutaj:

Https://sourceware.org/bugzilla/show_bug.cgi?id=9939

Będziesz musiał rozważyć alternatywne techniki, takie jak ElectricFence, valgrind, dmalloc, itp.

Więc, jeśli masz na myśli "are the malloc() and free() functions threadsafe", odpowiedź brzmi tak. Ale jeśli masz na myśli, "jest cały malloc / free suite threadsafe", odpowiedź brzmi nie.

 4
Author: breakpoint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 18:44:35

To zależy od tego, z jakiej implementacji biblioteki uruchomieniowej C korzystasz. Jeśli używasz na przykład MSVC, to istnieje opcja kompilatora, która pozwala określić, z którą wersją biblioteki chcesz zbudować (np. bibliotekę wykonywalną, która obsługuje wielowątkowość, będąc Bezpieczna lub nie).

 1
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-13 02:32:34

Nie, to nie jest bezpieczne dla wątków. W bibliotece C mogą być dostępne funkcje malloc_lock() i malloc_unlock(). Wiem, że istnieją one dla Biblioteki Newlib. Musiałem użyć tego, aby zaimplementować mutex dla mojego procesora, który jest wielowątkowy w sprzęcie.

 1
Author: sybreon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-13 03:02:28

Malloc i free nie są reentrantowe, ponieważ używają statycznej struktury danych, która rejestruje, jakie bloki pamięci są wolne. W rezultacie nie są reentrantowane żadne funkcje biblioteczne, które przydzielają lub zwalniają pamięć.

 1
Author: user3379688,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 07:09:10
 0
Author: Paul Sonier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-13 02:25:09

Krótka odpowiedź: Tak, od C11, który jest pierwszą wersją standardu C, która zawiera pojęcie wątków, malloc i przyjaciele są zobowiązani do bezpiecznego wątku. Wiele systemów operacyjnych, które zawierały zarówno wątki, jak i środowisko uruchomieniowe C, zapewniło tę gwarancję na długo przed standardem C, ale nie jestem przygotowany, aby przysięgać wszystkim. Jednak malloc i przyjaciele nie są i nigdy nie byli zobowiązani do bycia reentrant.

Oznacza to, że można bezpiecznie dzwonić malloc i free z wielu wątki jednocześnie i nie martw się o blokowanie, o ile nie łamiesz żadnej z innych zasad alokacji pamięci (np. wywołanie free raz i tylko raz na każdym wskaźniku zwracanym przez malloc). Ale nie jest bezpieczne wywoływanie tych funkcji z obsługi sygnału, który mógł przerwać wywołanie do malloc lub free w wątku obsługującym sygnał. Czasami, korzystając z funkcji wykraczających poza ISO C, można zagwarantować, że wątek obsługujący sygnał nie przerwał połączenia do malloc lub free, np. z sigprocmask i sigpause, ale staraj się tego nie robić, chyba że nie masz innej opcji, ponieważ trudno jest uzyskać idealną rację.


Długa odpowiedź z cytatami: standard C dodał koncepcję wątków w wersji 2011 (link do dokumentu N1570, który jest najbliższym przybliżeniem oficjalnego tekstu standardu 2011, który jest publicznie dostępny bezpłatnie). W tej rewizji sekcja 7.1.4 paragraf 5 stwierdza:

O ile w poniższych szczegółowych opisach nie określono inaczej, funkcje biblioteczne zapobiegają wyścigom danych w następujący sposób: funkcja biblioteczna nie ma bezpośredniego ani pośredniego dostępu do obiektów dostępnych przez wątki inne niż bieżący wątek, chyba że obiekty są dostępne bezpośrednio lub pośrednio poprzez argumenty funkcji. Funkcja biblioteczna nie może bezpośrednio ani pośrednio modyfikować obiektów dostępnych dla wątków innych niż bieżący wątek, chyba że obiekty są dostępne bezpośrednio lub pośrednio poprzez argumenty nie-const funkcji. Implementacje mogą współdzielić własne obiekty wewnętrzne między wątkami, jeśli obiekty te nie są widoczne dla użytkowników i są chronione przed wyścigami danych.

[przypis: oznacza to na przykład, że implementacja nie może używać obiektu statycznego do celów wewnętrznych bez synchronizacji, ponieważ może to spowodować wyścig danych nawet w programach, które nie współdzielą bezpośrednio obiektów między wątkami. Podobnie, implementacja memcpy nie może kopiować bajtów poza określoną długość obiektu docelowego, a następnie przywracać oryginalne wartości, ponieważ mogłoby to spowodować wyścig danych, gdyby program dzielił te bajty między wątki.]

Jak rozumiem, jest to długi sposób na powiedzenie, że funkcje biblioteczne zdefiniowane przez standard C muszą być bezpieczne dla wątków (w zwykłym znaczeniu: można je wywoływać z wielu wątków jednocześnie, bez blokowania jeśli nie dojdzie do kolizji danych przekazywanych jako argumenty), chyba że dokumentacja dla konkretnej funkcji wyraźnie mówi, że tak nie jest.]}

Następnie, 7.22.3P2 potwierdza, że malloc, calloc, realloc, aligned_alloc i free w szczególności są bezpieczne dla wątków:

W celu określenia istnienia rasy danych, funkcje alokacji pamięci zachowują się tak, jakby uzyskiwały dostęp tylko do miejsc pamięci dostępnych poprzez swoje argumenty, a nie inne statyczne przechowywanie czasu. Funkcje te mogą jednak w widoczny sposób modyfikować pamięć masową, którą przydzielają lub dealokują. Wywołanie free lub realloc, które deallocuje region P pamięci synchronizuje się z każdym wywołaniem alokacji, które przydziela cały lub część regionu P. Ta synchronizacja następuje po każdym dostępie p przez funkcję deallocacji, a przed każdym takim dostępem przez funkcję alokacji.

Kontrast tego, co mówi o strtok, który nie jest i nigdy nie był thread-safe, in 7.24.5. 8p6 :

Funkcja strtok nie jest wymagana, aby uniknąć wyścigów danych z innymi wywołaniami funkcji strtok.

[przypis: zamiast tego można użyć funkcji strtok_s, aby uniknąć wyścigów danych.]

(komentarz do przypisu: nie używaj strtok_s, używaj strsep.)

Starsze wersje standardu C nie mówiły nic o bezpieczeństwie gwintów. Jednak czy mówią coś o reentrancy, ponieważ sygnały zawsze były częścią standardu C. I to jest to, co powiedzieli, wracając do oryginalnego 1989 ANSI C standard (ten dokument ma prawie identyczne brzmienie do, ale bardzo różni się numeracją sekcji od, normy ISO C, który wyszedł w następnym roku): {]}

Jeśli sygnał [a] wystąpi inaczej niż w wyniku wywołania przerwania lub funkcji raise, zachowanie jest niezdefiniowane, jeśli obsługa sygnału wywołuje dowolną funkcję w bibliotece standardowej inną niż sygnał sama funkcja lub odnosi się do dowolnego obiektu o statycznym czasie przechowywania inne niż przypisanie wartości do statycznej zmiennej czasu przechowywania typu volatile sig_atomic_t . Ponadto, jeżeli takie wezwanie do funkcja signal zwraca sig_err, wartość errno wynosi nieokreślony.

Co jest długim sposobem na powiedzenie, że funkcje biblioteki C są , a nie muszą być reentrantowane jako ogólna zasada. Bardzo podobne sformułowanie wciąż pojawia się w C11, 7.14.1. 1p5 :

Jeśli sygnał [A] występuje inaczej niż w wyniku wywołania funkcji abort lub raise, zachowanie jest niezdefiniowane, jeśli obsługa sygnału odnosi się do dowolnego obiektu o statycznym lub wątkowym czasie przechowywania, który nie jest bez blokady atomowym obiektem innym niż przypisanie wartości do obiektu zadeklarowanego jako volatile sig_atomic_t, lub obsługa sygnału wywołuje dowolną funkcję w bibliotece standardowej inną niż funkcja abort, funkcja _Exit, funkcja quick_exit, lub funkcja sygnału z pierwszym argumentem równym liczbie sygnału odpowiadającej sygnałowi, który spowodował wywołanie funkcji obsługi. Ponadto, jeśli takie wywołanie funkcji sygnału spowoduje powrót SIG_ERR, wartość errno jest nieokreślona.

[przypis: jeśli jakikolwiek sygnał jest generowany przez asynchroniczną obsługę sygnału, zachowanie jest niezdefiniowane.]

POSIX wymaga znacznie dłuższego, ale wciąż krótszego w porównaniu do ogólnego rozmiaru C library , list of functions to be safely called from an "asynchronous signal handler", and also defined in more details the circumstances, in which a signal may " existing other than as a result of calling the abort or raise function."Jeśli robisz coś nietrywialnego z sygnałami, prawdopodobnie piszesz kod przeznaczony do uruchomienia na systemie operacyjnym o naturze Unix (w przeciwieństwie do Windows, MVS lub czegoś osadzonego, które prawdopodobnie nie mają pełnej hostowanej implementacji C w pierwsze miejsce), a powinieneś zapoznać się z wymaganiami POSIX dla nich, a także wymaganiami ISO C.

 0
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 19:38:54