[c] 스레드에 고유 한 힙이 있습니까?

내가 아는 한 각 스레드는 스레드가 운영 체제에 의해 생성 될 때 고유 한 스택을 얻습니다. 각 스레드에 고유 한 힙이 있는지 궁금합니다.



답변

아니오. 모든 스레드는 공통 힙을 공유합니다.

스레드에는 항목을 빠르게 추가하고 제거 할 수 있는 개인 스택 이 있습니다. 이렇게하면 스택 기반 메모리가 빨라지지만 무한 재귀에서 발생하는 것처럼 스택 메모리를 너무 많이 사용하면 스택 오버플로가 발생합니다.

모든 스레드가 동일한 힙을 공유하므로 할당 자 / 할당 해제 자에 대한 액세스가 동기화되어야합니다. 할당 자 경합 을 피하기위한 다양한 방법과 라이브러리가 있습니다.

일부 언어에서는 단일 스레드에 할당 할 수있는 개별 메모리 풀 또는 개별 힙을 만들 수 있습니다.


답변

기본적으로 C에는 단일 힙만 있습니다.

즉, 스레드를 인식하는 일부 할당자는 각 스레드가 할당 할 자체 영역을 갖도록 힙을 분할합니다. 아이디어는 이것이 힙 스케일을 향상시켜야한다는 것입니다.

이러한 힙의 한 예는 Hoard 입니다.


답변

OS에 따라 다릅니다. Windows 및 Uniice의 표준 C 런타임은 스레드간에 공유 힙을 사용합니다. 이것은 모든 malloc / free 잠금을 의미합니다.

예를 들어 Symbian에서는 스레드가 모든 힙에 할당 된 데이터에 대한 포인터를 공유 할 수 있지만 각 스레드는 자체 힙과 함께 제공됩니다. Symbian의 디자인은 할당 / 해제 중에 잠금의 필요성을 제거 할뿐만 아니라 스레드 간의 데이터 소유권에 대한 명확한 사양을 장려하기 때문에 제 생각에 더 좋습니다. 또한이 경우 스레드가 죽으면 할당 된 모든 객체를 함께 가져옵니다. 즉, 할당 된 객체를 누수 할 수 없습니다. 이는 메모리가 제한된 모바일 장치에서 가져야하는 중요한 속성입니다.

Erlang은 또한 “프로세스”가 가비지 수집 단위로 작동하는 유사한 디자인을 따릅니다. 모든 데이터는 복사를 통해 프로세스간에 전달됩니다. 단, 참조 횟수가 계산되는 이진 blob은 제외됩니다.


답변

각 스레드에는 자체 스택과 호출 스택이 있습니다.

각 스레드는 동일한 힙을 공유합니다.


답변

“힙”을 말할 때 정확히 무슨 뜻인지에 따라 다릅니다.

모든 스레드는 주소 공간을 공유하므로 힙 할당 개체는 모든 스레드에서 액세스 할 수 있습니다. 기술적으로 스택도 이러한 의미에서 공유됩니다. 즉, 다른 스레드의 스택에 액세스하는 것을 방해하는 것은 없습니다 (그렇게하는 것이 거의 의미가 없습니다).

반면에 메모리를 할당하는 데 사용되는 힙 구조 가 있습니다 . 여기서 힙 메모리 할당에 대한 모든 부기가 수행됩니다. 이러한 구조는 스레드 간의 경합을 최소화하도록 정교하게 구성되어 있으므로 일부 스레드는 힙 구조 (아레나)를 공유 할 수 있고 일부는 별개의 아레나를 사용할 수 있습니다.
세부 사항에 대한 훌륭한 설명은 다음 스레드를 참조하십시오. malloc은 다중 스레드 환경에서 어떻게 작동합니까?


답변

일반적으로 스레드는 힙 및 기타 리소스를 공유하지만 그렇지 않은 스레드와 유사한 구성이 있습니다. 스레드와 유사한 구조 중에는 Erlang의 경량 프로세스와 UNIX의 전체 프로세스 (를 호출하여 생성됨 fork())가 있습니다. 다중 시스템 동시성에 대해 작업 할 수도 있습니다.이 경우 스레드 간 통신 옵션이 상당히 제한됩니다.


답변

일반적으로 모든 스레드는 동일한 주소 공간을 사용하므로 일반적으로 힙이 하나만 있습니다.

그러나 조금 더 복잡 할 수 있습니다. TLS ( Thread Local Storage)를 찾고있을 수 있지만 단일 값만 저장합니다.

Windows 관련 : TLS 공간은 TlsAlloc을 사용하여 할당 하고 TlsFree를 사용하여 해제 할 수 있습니다 ( 여기에서 개요 참조 ). 다시 말하지만, 힙이 아니라 DWORD뿐입니다.

이상하게도 Windows 는 프로세스 당 여러 힙을 지원 합니다. 힙의 핸들을 TLS에 저장할 수 있습니다. 그러면 “Thread-Local Heap”과 같은 것이 있습니다. 그러나 핸들 만 다른 스레드에 알려지지 않고 여전히 동일한 주소 공간이므로 포인터를 사용하여 메모리에 액세스 할 수 있습니다.

편집 : 일부 메모리 할당 자 (특히 FreeBSD의 jemalloc )는 TLS를 사용하여 스레드에 “영역”을 할당합니다. 이는 동기화 오버 헤드를 줄여 다중 코어에 대한 할당을 최적화하기 위해 수행됩니다.