堆栈限制和线程之间的关系
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 - %ldn", 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-generic#48-Ubuntu SMP Wed Nov 24 10:14:11 UTC 2010 x86_64 GNU / Linux
在UNIX / Linux上, getrlimit(RLIMIT_STACK)
只能保证主线程堆栈的大小。 OpenGroup的引用是明确的,“初始线程的堆栈”:
http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html
对于Linux,有一个引用指出RLIMIT_STACK
是默认情况下用于任何线程堆栈(用于NPTL线程)的内容:
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html
通常,由于程序员可以决定(通过在创建线程时使用非标准属性)放置堆栈的位置和/或为新线程使用多少堆栈,因此不存在“累积进程堆栈限制”这样的事情。 它来自总RLIMIT_AS
地址空间大小。
但你必须对线程的数量,您可以创建,限制sysconf(PTHREAD_THREADS_MAX)
和你有最小尺寸线程栈必须具备的,下限sysconf(PTHREAD_STACK_MIN)
此外,您可以查询新线程的默认堆栈大小:
pthread_attr_t attr;
size_t stacksize;
if (!pthread_attr_init(&attr) && !pthread_attr_getstacksize(&attr, &stacksize))
printf("default stacksize for a new thread: %ldn", stacksize);
即默认 - 初始化一组pthread属性并询问系统为您提供的堆栈大小。
在一个线程程序中,所有线程的栈(除了最初的那个)都从堆中分配出来,所以RLIMIT_STACK
与你的线程可以使用多少栈空间几乎没有关系。
上一篇: Relation between stack limit and threads
下一篇: What parts of a process' virtual address space are overwriteable?