malloc은 스레드로부터 안전합니까?
은 IS malloc()
기능의 재진입은?
나는 어딘가에서 -pthread로 컴파일하면 malloc이 스레드로부터 안전하다는 것을 읽었습니다. 하지만 malloc은 ANSI C이고 스레드는 그렇지 않기 때문에 구현에 의존적이라고 확신합니다.
gcc를 말하는 경우 :
-pthread 및 malloc ()을 사용한 컴파일 및 링크는 x86 및 AMD64에서 스레드로부터 안전합니다.
더 통찰력있는 또 다른 의견
glibc-2.2 +의 {malloc, calloc, realloc, free, posix_memalign}은 스레드로부터 안전합니다.
http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2005-07/0323.html
질문 : "malloc 재진입"입니까?
답변 : 아닙니다. 다음은 일상적인 재진입을 만드는 것에 대한 한 가지 정의입니다 .
malloc의 일반적인 버전은 재 입력을 허용하지 않습니다 (예 : 신호 처리기에서). 재진입 루틴이 잠금을 사용하지 않을 수 있으며, 현존하는 거의 모든 malloc에 버전이 사용 잠금 (만드는 그들 스레드 안전), 또는 전역 / 정적 변수를 (만드는 그들 스레드 안전하지 않음을 노트 및 비 재진입).
지금까지의 모든 대답은 완전히 다른 질문 인 "malloc 스레드로부터 안전합니까?"라고 대답했습니다. 에 그 질문 대답은 그것을 따라 런타임 라이브러리, 그리고 아마도 컴파일러 플래그를 사용. 최신 UNIX에서는 기본적으로 스레드로부터 안전한 malloc이 제공됩니다. 윈도우, 사용에 /MT
, /MTd
, /MD
또는 /MDd
플래그는 스레드 안전 런타임 라이브러리를 얻을 수 있습니다.
다음은 glibc의 malloc.c에서 발췌 한 것입니다.
스레드 안전성 : NO_THREADS가 정의되지 않은 경우 스레드 안전성
NO_THREADS가 기본적으로 정의되어 있지 않다고 가정하면 malloc은 적어도 리눅스에서는 스레드로부터 안전합니다.
이것은 꽤 오래된 질문이며 현재 상황에 따라 신선함을 가져오고 싶습니다.
예, 현재 malloc()
스레드로부터 안전합니다.
로부터 GNU C 라이브러리 참조 설명서 의 glibc-2.20 [released 2014-09-07]
:
void * malloc (size_t size)
예비 : MT-Safe | ...
... 1.2.2.1 POSIX 안전 개념 :
... MT-Safe 또는 Thread-Safe 함수는 다른 스레드가있을 때 호출해도 안전합니다. MT-Safe에서 MT는 Multi Thread를 나타냅니다.
MT-Safe는 기능이 원자 적이라는 것을 의미하지 않으며 POSIX가 사용자에게 노출하는 메모리 동기화 메커니즘을 사용하지 않습니다. MT-Safe 함수를 순서대로 호출해도 MT-Safe 조합이 생성되지 않을 수도 있습니다. 예를 들어, 스레드가 두 개의 MT-Safe 함수를 차례로 호출하는 것은 다른 스레드의 동시 호출이 파괴적인 방식으로 간섭 할 수 있으므로 두 함수의 조합의 원자 적 실행과 동등한 동작을 보장하지 않습니다.
라이브러리 인터페이스에서 함수를 인라인 할 수있는 전체 프로그램 최적화는 안전하지 않은 재정렬을 노출 할 수 있으므로 GNU C 라이브러리 인터페이스에서 인라인을 수행하는 것은 권장되지 않습니다. 문서화 된 MT-Safety 상태는 전체 프로그램 최적화를 보장하지 않습니다. 그러나 사용자가 볼 수있는 헤더에 정의 된 함수는 인라인에 안전하도록 설계되었습니다.
예, POSIX.1-2008 malloc
에서는 스레드로부터 안전합니다.
2.9.1 스레드 안전성
POSIX.1-2008의이 볼륨에 정의 된 모든 함수는 스레드로부터 안전해야합니다. 단, 다음 함수 1는 스레드로부터 안전 할 필요가 없습니다.
[포함되지 않은 함수 목록
malloc
]
GLIBC와 함께 일하는 경우 대답은 예, 그러나입니다.
특히, 그렇습니다.하지만 malloc과 free는 스레드로부터 안전 하지만 디버깅 기능은 그렇지 않다는 점에 유의하십시오 .
특히 매우 유용한 mtrace (), mcheck () 및 mprobe () 함수 는 스레드로부터 안전하지 않습니다 . GNU 프로젝트에서 볼 수있는 가장 짧고 직접적인 답변 중 하나는 여기에 설명되어 있습니다.
https://sourceware.org/bugzilla/show_bug.cgi?id=9939
ElectricFence, valgrind, dmalloc 등과 같은 대체 기술을 고려해야합니다.
따라서 "malloc () 및 free () 함수가 스레드로부터 안전합니다"라는 뜻이라면 대답은 '예'입니다. 그러나 "전체 malloc / free 제품군 스레드 세이프"를 의미하는 경우 대답은 아니오입니다.
짧은 답변 : 예, 스레드 개념을 포함하는 C 표준의 첫 번째 버전 인 C11부터는 malloc
스레드로부터 안전해야합니다. 스레드와 C 런타임을 모두 포함하는 많은 운영 체제는 C 표준이 적용되기 훨씬 전에이를 보장했지만 모든 . 그러나 malloc
친구는 재진입이 필요하지 않으며 결코 요구되지 않았습니다.
그 수단은 전화를 안전 malloc
하고 free
동시에이 아니라 여러 스레드만큼 당신이 메모리 할당의 다른 규칙의 위반하지 않는 한 잠금에 대한 걱정에서 (예를 들어 전화 free
한 번만에 의해 반환 된 각 포인터 malloc
). 그러나 신호를 처리하는 스레드 또는 호출을 중단했을 수있는 신호 처리기에서 이러한 함수를 호출하는 것은 안전 하지 않습니다 . 때로는 ISO C 이외의 기능을 사용하여 신호를 처리하는 스레드가 또는에 대한 호출을 중단하지 않았 음을 보장 할 수 있습니다 ( 예 : and ).하지만 다른 옵션이없는 경우를 제외하고는 완벽하게 옳게하기가 어렵 기 때문에 그렇게하지 마십시오.malloc
free
malloc
free
sigprocmask
sigpause
인용이 포함 된 긴 답변 : C 표준은 2011 개정판 에 스레드 개념을 추가했습니다 (링크는 무료로 공개적으로 제공되는 2011 표준의 공식 텍스트에 가장 가까운 문서 N1570에 대한 것입니다). 이 개정판에서 섹션 7.1.4 단락 5 는 다음과 같이 설명합니다.
다음의 자세한 설명에서 명시 적으로 언급하지 않는 한, 라이브러리 함수는 다음과 같이 데이터 경합을 방지해야합니다. 라이브러리 함수는 함수의 인수를 통해 직접 또는 간접적으로 개체에 액세스하지 않는 한 현재 스레드 이외의 스레드에서 액세스 할 수있는 개체에 직접 또는 간접적으로 액세스해서는 안됩니다. . 라이브러리 함수는 객체가 함수의 상수가 아닌 인수를 통해 직접 또는 간접적으로 액세스되지 않는 한 현재 스레드가 아닌 스레드에서 액세스 할 수있는 객체를 직접 또는 간접적으로 수정해서는 안됩니다. 객체가 사용자에게 표시되지 않고 데이터 경합으로부터 보호되는 경우 구현은 스레드간에 자체 내부 객체를 공유 할 수 있습니다.
[각주 : 이것은 예를 들어, 스레드간에 객체를 명시 적으로 공유하지 않는 프로그램에서도 데이터 경합을 유발할 수 있기 때문에 동기화없이 내부 목적으로 정적 객체를 사용하는 구현이 허용되지 않음을 의미합니다. 마찬가지로 memcpy 구현은 지정된 길이의 대상 객체를 초과하여 바이트를 복사 한 다음 원래 값을 복원하는 것이 허용되지 않습니다. 프로그램이 스레드간에 해당 바이트를 공유하면 데이터 경합을 일으킬 수 있기 때문입니다.]
As I understand it, this is a long-winded way of saying that the library functions defined by the C standard are required to be thread-safe (in the usual sense: you can call them from multiple threads simultaneously, without doing any locking yourself, as long as they don't end up clashing on the data passed as arguments) unless the documentation for a specific function specifically says it isn't.
Then, 7.22.3p2 confirms that malloc, calloc, realloc, aligned_alloc, and free in particular are thread-safe:
For purposes of determining the existence of a data race, memory allocation functions behave as though they accessed only memory locations accessible through their arguments and not other static duration storage. These functions may, however, visibly modify the storage that they allocate or deallocate. A call to free or realloc that deallocates a region p of memory synchronizes with any allocation call that allocates all or part of the region p. This synchronization occurs after any access of p by the deallocating function, and before any such access by the allocating function.
Contrast what it says about strtok, which is not and never has been thread-safe, in 7.24.5.8p6:
The strtok function is not required to avoid data races with other calls to the strtok function.
[footnote: The strtok_s function can be used instead to avoid data races.]
(comment on the footnote: don't use strtok_s
, use strsep
.)
Older versions of the C standard said nothing whatsoever about thread safety. However, they did say something about reentrancy, because signals have always been part of the C standard. And this is what they said, going back to the original 1989 ANSI C standard (this document has nigh-identical wording to, but very different section numbering from, the ISO C standard that came out the following year):
If [a] signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler calls any function in the standard library other than the signal function itself or refers to any object with static storage duration other than by assigning a value to a static storage duration variable of type volatile sig_atomic_t . Furthermore, if such a call to the signal function results in a SIG_ERR return, the value of errno is indeterminate.
Which is a long-winded way of saying that C library functions are not required to be reentrant as a general rule. Very similar wording still appears in C11, 7.14.1.1p5:
If [a] signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomic_t, or the signal handler calls any function in the standard library other than the abort function, the _Exit function, the quick_exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler. Furthermore, if such a call to the signal function results in a SIG_ERR return, the value of errno is indeterminate.
[footnote: If any signal is generated by an asynchronous signal handler, the behavior is undefined.]
POSIX requires a much longer, but still short compared to the overall size of the C library, list of functions to be safely callable from an "asynchronous signal handler", and also defines in more detail the circumstances under which a signal might "occur other than as the result of calling the abort or raise function." If you're doing anything nontrivial with signals, you are probably writing code intended to be run on an OS with the Unix nature (as opposed to Windows, MVS, or something embedded that probably doesn't have a complete hosted implementation of C in the first place), and you should familiarize yourself with the POSIX requirements for them, as well as the ISO C requirements.
It depends on which implementation of the C runtime library you're using. If you're using MSVC for example then there's a compiler option which lets you specify which version of the library you want to build with (i.e. a run-time library that supports multi-threading by being tread-safe, or not).
No, it is not thread-safe. There may actually be a malloc_lock()
and malloc_unlock()
function available in your C library. I know that these exist for the Newlib library. I had to use this to implement a mutex for my processor, which is multi-threaded in hardware.
malloc and free are not reentrant, because they use a static data structure which records what memory blocks are free. As a result, no library functions that allocate or free memory are reentrant.
No, it is not.
Web archive link (original has gone dead)
참고URL : https://stackoverflow.com/questions/855763/is-malloc-thread-safe
'Program Tip' 카테고리의 다른 글
어댑터에서 부모 RecyclerView에 대한 참조를 얻는 더 좋은 방법이 있습니까? (0) | 2020.10.31 |
---|---|
Swift에서 where 절을 사용하여 배열 유형 확장 (0) | 2020.10.31 |
Haskell Cont 모나드는 어떻게 그리고 왜 작동합니까? (0) | 2020.10.31 |
BigDecimal을 최대 2 개의 십진수로 문자열로 포맷하고 소수점 부분에서 0을 제거합니다. (0) | 2020.10.31 |
플롯 창이 응답하지 않음 (0) | 2020.10.31 |