堆栈限制和线程之间的关系 [英] Relation between stack limit and threads
问题描述
-
ulimit -s
>与Linux实现(或与此相关的任何OS)中的堆栈大小(在线程级别)之间是什么关系?
What is the relationship between ulimit -s
<value
> and the stack size (at thread level) in the Linux implementation (or for that matter any OS)?
Is <number of threads
> * <each thread stack size
> must be less than < stack size assigned by ulimit command
> valid justification?
在下面的程序中-每个线程分配char [PTHREAD_STACK_MIN]并创建10个线程.但是,当ulimit设置为10 * PTHREAD_STACK_MIN时,由于中止而不会进行核心转储.对于某些堆栈大小的随机值(远远小于10 * PTHREAD_STACK_MIN),它会进行核心转储.为什么这样?
In the below program - each thread allocates char [PTHREAD_STACK_MIN] and 10 threads are created. But when the ulimit is set to 10 * PTHREAD_STACK_MIN, it does not coredump due to abort. For some random value of stacksize (much less than 10 * PTHREAD_STACK_MIN), it core dumps. Why so?
我的理解是,堆栈大小表示所有线程在该过程的总和中所占用的堆栈.
My Understanding is that stacksize represents the stack occupied by all the threads in summation for the process.
线程功能
#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 Wed Nov 24 10:14:11 UTC 2010 x86_64 GNU/Linux
PS:
I am using Ubuntu 10.04 LTS version, with below specification.
Linux laptop 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的引用在初始线程的堆栈"上是明确的:
On UNIX/Linux, getrlimit(RLIMIT_STACK)
is only guaranteed to give the size of the main thread's stack. The OpenGroup's reference is explicit on that, "initial thread's stack":
http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html
对于Linux,有一个引用表明RLIMIT_STACK
是默认情况下将用于所有线程堆栈(用于NPTL线程)的内容:
For Linux, there's a reference which indicates that RLIMIT_STACK
is what will be used by default for any thread stack (for NPTL threading):
http://www.kernel. org/doc/man-pages/online/pages/man3/pthread_create.3.html
通常,由于程序员可以(通过在创建线程时使用非标准属性)决定将堆栈放置在何处和/或用于新线程的堆栈数,因此不存在累积过程堆栈限制"之类的问题. ".而是从RLIMIT_AS
地址空间的总大小中得出的.
但是您确实对可以创建的线程数有所限制,sysconf(PTHREAD_THREADS_MAX)
,对于线程堆栈必须具有的最小大小,也确实有一个下限,sysconf(PTHREAD_STACK_MIN)
.
Generally, since the programmer can decide (by using nonstandard attributes when creating the thread) where to put the stack and/or how much stack to use for a new thread, there is no such thing as a "cumulative process stack limit". It rather comes out of the total RLIMIT_AS
address space size.
But you do have a limit on the number of threads you can create,sysconf(PTHREAD_THREADS_MAX)
, and you do have a lower limit for the minimum size a thread stack must have,sysconf(PTHREAD_STACK_MIN)
.
此外,您可以查询默认堆栈大小以获取新线程:
Also, you can query the default stacksize for new threads:
pthread_attr_t attr;
size_t stacksize;
if (!pthread_attr_init(&attr) && !pthread_attr_getstacksize(&attr, &stacksize))
printf("default stacksize for a new thread: %ld\n", stacksize);
即默认初始化一组pthread属性,并询问系统为您提供了什么堆栈大小.
I.e. default-initialize a set of pthread attributes and ask for what stacksize the system gave you.
这篇关于堆栈限制和线程之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!