2009-12-04 4 views
1

C 프로그래밍 언어와 NPTL 2.6을 사용하는 멀티 스레드 모듈러 응용 프로그램을 개발 중입니다. 각 플러그인에 대해 POSIX 스레드가 작성됩니다. 문제는 기본 스택 크기가 사용자의 선택에 달려 있기 때문에 각 스레드마다 고유 한 스택 영역이 있기 때문에 경우에 따라 큰 메모리 소비가 발생할 수 있습니다.NPTL 기본 스택 크기 문제

pthread_attr_t attr; 
pthread_attr_init (&attr); 
pthread_attr_getstacksize(&attr, &st1); 
if(pthread_attr_setstacksize (&attr, MODULE_THREAD_SIZE) != 0) perror("Stack ERR"); 
pthread_attr_getstacksize(&attr, &st2); 
printf("OLD:%d, NEW:%d - MIN: %d\n", st1, st2, PTHREAD_STACK_MIN); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
/* "this" is static data structure that stores plugin related data */ 
pthread_create(&this->runner, &attr, (void *)(void *)this->run, NULL); 

편집 I : :는 pthread_create() 섹션이 추가

내가 각 스레드를 작성하기 전에 스택 크기를 변경하려면이 비슷한을 사용하여 불필요한 메모리 사용을 방지합니다.

내가 예상대로이 일을 작동하지 않았다는 pthread_attr_getstacksize()에 의해보고 된 스택 크기가 변경 되나 (PS/최고/pmap의 출력에서) 응용 프로그램의 총 메모리 사용량은 변경되지 않았다

OLD : 10485760 , 새로운 : 65536 - MIN : 나는 응용 프로그램을 시작하기 전에 ulimit -s MY_STACK_SIZE_LIMIT를 사용하는 경우 16384

나는 예상 된 결과를 얻을 수 있습니다.

내 질문은 :

1) 물론 스레드)를 작성하기 전에 (응용 프로그램을 시작한 후 (기본) 스레드 스택 크기를 변경하는 모든 휴대용 (UNIX 변종 사이) 방법이 있나요?

2) 모든 스레드에 동일한 스택 영역을 사용할 수 있습니까?

3) 많은 고통없이 스레드에 대한 스택을 완전히 비활성화 할 수 있습니까?

+0

바보 같은 질문이지만'pthread_attr_setstacksize()'를 통해 스택 크기를 수정 한 후에 스레드를 실제로 만들 때'attr'을 사용합니까? 'pthread_create()'를 어떻게 호출하는지 볼 수 있습니까? –

+0

물론, 내 게시물을 업데이 트했습니다. –

답변

2

# 2 및 # 3에 대한 대답은 아니오 및 아니오입니다. 각 스레드는 스택을 필요로합니다 (로컬 변수와 리턴 어드레스는 다른 곳에서 실행됩니까?). 스레드마다 고유해야합니다. 그렇지 않으면 스레드가 서로의 로컬 변수를 덮어 쓰고 주소를 반환하여 모두 충돌시킵니다.

# 1 ... 스택 크기 호출이 정확하게 이에 대한 대답입니다. 나는 당신이 쓰레드를 만들 수있는 크기를 알아내어 그것을 설정하는 것이 좋습니다.

top .... top에서 일이 올바르게 보이지 않는 이유는 메모리 사용에 관한 악명 높은 거짓말 쟁이입니다. :-) 물건이 실제로 할당되지 않았거나 OOM이 죽게 되나요? 스레드 작성에 실패 했습니까? 디스크에 대한 성능 저하 및 페이징 증가가 있습니까? 이 질문에 대한 대답이 '아니오'라면, 나는 걱정할 것이별로 없다고 생각합니다.

아래 및 위의 몇 가지 주석을 기반으로 한 업데이트 :
우선 16KB는 많은 스택 공간이 필요하지 않은 것으로 여겨지지만 여전히 큰 편입니다. 정말 작게 지내고 싶다면 x86 Linux에서 4096 또는 8192라고 말하고 싶습니다. 둘째, 네, CPU의 스택 포인터를 다른 것으로 설정할 수 있습니다. 그러나 malloc() 또는 mmap()이되면 공간을 차지하게됩니다. 스택 포인터를 다른 것으로 설정하는 것이 어떻게 도움이 될지 모르겠습니다. 만약 당신이 정말로 main()을 호출하는 쓰레드가 스택이 너무 큽니다. (제가 약간 미쳤다고 말할 것입니다) 그리고 pthread_attr_setstacksize()은 당신이 충분히 작아 보이지 않도록합니다. clone() 시스템 호출을 호출하고 메인 스레드의 스택 포인터 또는 다른 곳의 버퍼를 기반으로 스택을 지정하여 스레드를 생성하는 것과 같은 이식성이없는 것들.하지만 여전히 각 스레드마다 스택이 필요할 것입니다. top이 여전히 실망 스럽습니다. 어쩌면 당신의 기대는 조금 높을 수 있습니다.

+0

그게 정확히 그가하고있는 일입니다. 그의 소스 2 행을 확인하십시오! – Puppe

+0

예 Puppe, 정확히 내가하고있는 일입니다. 받아 들일 수있는 스택 크기로도 예상했던 것처럼 나쁘지 않습니다. Q3에 관해서는, 제 3 자 라이브러리가 있어도 프로세스를 위해 스택을 사용할 수 없게 할 것이라고 확신합니다. 그래서 힙에 스택을 시뮬레이트하는 방법이 있어야합니다. –

+0

@eyazici - 알았어, 스택 포인터는 CPU 레지스터이며 malloc() 또는 mmap()에서 얻은 것을 포함하여 원하는대로 설정할 수 있습니다. 하지만 귀하의 질문에 나는 그것이 당신이 묻고있는 것이 무엇인지 전혀 몰랐습니다. 그리고 어딘가에서 얻었을지라도 스택은 여전히 ​​남아 있습니다. 여전히 메모리 등을 소비 할 것입니다. – asveikau

1

이 문제도 확인했습니다. 스택이 어떻게 계산되는지는 분명하지 않지만 "추가"공간은 전체 VM에 대해 계산됩니다. 프로세스 경계에 대해 실행하면 문제가 있습니다 (공간을 사용하지 않아도). 실행중인 Linux 버전 (2.6 제품군 내조차도)과 32 비트인지 64 비트인지에 따라 달라집니다.

+0

32 비트 CentOS 릴리즈 5.3, 커널 2.6.18 –