ulimit -s
<value
>和Linux實現(或任何操作系統)中堆棧大小(線程級別)之間的關係是什麼?堆棧限制和線程之間的關係是
<number of threads
> *<each thread stack size
>必須小於< stack size assigned by ulimit command
>有效的理由?在下面的程序中 - 每個線程分配char [PTHREAD_STACK_MIN]並創建10個線程。但是當ulimit被設置爲10 * PTHREAD_STACK_MIN時,它不會因爲中止而導致內核崩潰。對於stacksize的一些隨機值(遠小於10 * PTHREAD_STACK_MIN),它是核心轉儲。爲什麼這樣?
我的理解是stacksize表示堆棧中所有線程在求和過程中佔用的堆棧。
線程函數
#include <cstdio>
#include <error.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/resource.h>
using namespace std;
#include <pthread.h>
#include <bits/local_lim.h>
const unsigned int nrOfThreads = 10;
pthread_t ntid[nrOfThreads];
void* thr_fn(void* argv)
{
size_t _stackSz;
pthread_attr_t _attr;
int err;
err = pthread_attr_getstacksize(&_attr,&_stackSz);
if(0 != err)
{
perror("pthread_getstacksize");
}
printf("Stack size - %lu, Thread ID - %llu, Process Id - %llu \n", static_cast<long unsigned int> (_stackSz), static_cast<long long unsigned int> (pthread_self()), static_cast<long long unsigned int> (getpid()));
//check the stack size by actual allocation - equal to 1 + PTHREAD_STACK_MIN
char a[PTHREAD_STACK_MIN ] = {'0'};
struct timeval tm;
tm.tv_sec = 1;
while (1)
select(0,0,0,0,&tm);
return ((void*) NULL);
}
主要功能
int main(int argc, char *argv[])
{
struct rlimit rlim;
int err;
err = getrlimit(RLIMIT_STACK,&rlim);
if(0 != err)
{
perror("pthread_create ");
return -1;
}
printf("Stacksize hard limit - %ld, Softlimit - %ld\n", static_cast <long unsigned int> (rlim.rlim_max) ,
static_cast <long unsigned int> (rlim.rlim_cur));
for(unsigned int j = 0; j < nrOfThreads; j++)
{
err = pthread_create(&ntid[j],NULL,thr_fn,NULL);
if(0 != err)
{
perror("pthread_create ");
return -1;
}
}
for(unsigned int j = 0; j < nrOfThreads; j++)
{
err = pthread_join(ntid[j],NULL);
if(0 != err)
{
perror("pthread_join ");
return -1;
}
}
perror("Join thread success");
return 0;
}
PS:
我使用Ubuntu 10.04 LTS版本,下面的規格。
Linux的膝上型2.6.32-26泛型#48的Ubuntu SMP星期三年11月24十時14分11秒UTC 2010 x86_64的GNU/Linux的
實際上,在UN * X上,堆棧默認通過`mmap(...,MAP_ANON | MAP_PRIVATE,...)分配,因此地址空間不相交的部分,而不是普通的部分(連續的內存,並通過`sbrk`)進程堆增長。如果您在調用`pthread_create()`之前手動創建了一個具有適當初始化值的`pthread_attr_t`,您可以選擇將一個線程堆棧放入堆中,但這很危險 - 堆棧溢出會簡單地破壞進程堆而不是運行到通常會在堆棧底部顯示未映射的redzone。 – 2010-12-06 17:53:47
@FrankH是的,這是真的;我過於鬆散地使用「堆」。 – 2010-12-06 17:55:22