堆栈限制和线程之间的关系

  1. 在Linux实现(或任何操作系统)中,ulimit -s <value >与堆大小(在线程级别)之间的关系是什么?

    <number of threads > * <each thread stack size >必须小于< stack size assigned by ulimit command >有效alignment?

  2. 在下面的程序中 – 每个线程分配char [PTHREAD_STACK_MIN]并创build10个线程。 但是,当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); } 

主function

 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-generic#48-Ubuntu SMP Wed Nov 24 10:14:11 UTC 2010 x86_64 GNU / Linux

Solutions Collecting From Web of "堆栈限制和线程之间的关系"

在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_THREADS_MAX) ,您有一个下限。

另外,您可以查询新线程的默认堆栈大小:

 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属性,并询问系统给你的堆栈大小。

在一个线程化的程序中,所有线程的堆栈(除了最初的那个)都是从堆中分配出来的,所以RLIMIT_STACK与你的线程可以使用多少堆栈空间几乎没有关系。