내가 이해한 바로는 Linux에서 pthread의 기본 스택 크기는 16K입니다. 64비트 Ubuntu 설치에서 이상한 결과가 나타납니다.
$ ulimit -s
8192
반품:
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Thread stack size = %d bytes \n", stacksize);
Prints
Thread stack size = 8388608 bytes
스택 크기가 "8388608"이 아니라고 확신합니다. 무엇이 잘못될 수 있나요?
답변1
사실, 당신의가상스택 크기예8388608바이트(8MB) 물론 이것이 사실이 아니라고 결론을 내리는 것은 당연합니다. 왜냐하면 각 스레드에 대해 해당 스택은 엄청난 양의 메모리를 소비하고 99%의 경우 몇 KB이면 충분할 것이기 때문입니다.
좋은 소식은 스레드가물리적실제로 필요한 메모리입니다. 이는 프로세서의 하드웨어 MMU(메모리 관리 장치)를 사용하여 운영 체제가 얻는 마법의 힘 중 하나입니다. 일어나는 일은 다음과 같습니다.
운영 체제는 스레드에 대한 MMU 페이지 테이블을 설정하여 스택에 8MB의 가상 메모리를 할당합니다. 페이지 테이블 항목을 보관하는 데에는 RAM이 거의 필요하지 않습니다.
스레드가 실행되어 아직 물리적 페이지가 할당되지 않은 스택의 가상 주소에 액세스하려고 시도하면 MMU는 "페이지 오류"라는 하드웨어 예외를 트리거합니다.
CPU 커널은 권한 있는 실행 모드(자체 스택 사용)로 전환하고 커널의 내부 페이지 오류 예외 처리기를 호출하여 페이지 오류 예외에 응답합니다.
커널은 물리적 RAM 페이지를 이 가상 메모리 페이지에 할당하고 이를 사용자 공간 스레드에 반환합니다.
이 작업은 사용자 공간 스레드에 표시되지 않습니다. 그 관점에서 보면 마치 메모리가 항상 거기에 있었던 것처럼 스택을 사용합니다. 동시에 스택은 스레드의 요구 사항을 충족하기 위해 자동으로 증가하거나 증가하지 않습니다.
MMU는 오늘날의 컴퓨터 시스템에서 중요한 하드웨어 부분입니다. 특히 시스템에서 많은 "마법"을 담당하므로 MMU의 기능과 가상 메모리 전반에 대해 자세히 알아보는 것이 좋습니다. 또한 애플리케이션이 성능에 민감하고 많은 양의 데이터를 처리하는 경우 TLB(MMU의 페이지 테이블 캐시)가 작동하는 방식과 데이터 또는 알고리즘을 재구성하여 TLB 적중률을 최대화하는 방법을 이해해야 합니다.
답변2
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
이
stacksize
속성은 생성된 스레드 스택에 할당된 최소 스택 크기(바이트)를 정의해야 합니다.
귀하의 예에서 스택 크기는 8388608바이트로 설정되어 있으며 이는 ulimit -s
So 명령에서 반환된 8MB에 해당하므로 일치합니다.
pthread_create()
설명 에서 :
존재하다리눅스/x86-32, 새 스레드의 기본 스택 크기는 다음과 같습니다.2MB. NPTL 스레드 구현에서 다음과 같은 경우 RLIMIT_STACK프로그램 시작 시 소프트 리소스 제한은 새 스레드의 기본 스택 크기를 결정하는 "무제한" 이외의 것입니다. 사용pthread_attr_setstacksize(3) 스택 크기 속성은 기본값이 아닌 스택 크기를 얻기 위해 스레드를 생성하는 데 사용되는 attr 매개변수에 명시적으로 설정할 수 있습니다.
따라서 스레드 스택 크기는 위의 설정 함수나 ulimit
시스템 속성을 통해 설정할 수 있습니다. 당신이 언급하는 16k의 경우 어떤 플랫폼에서 이것을 보았는지 및/또는 이에 대해 설정된 시스템 제한이 있는지 확실하지 않습니다.
보다pthread_create 페이지그리고여기몇 가지 흥미로운 예입니다.