Relation between stack limit and threads
c++, linux, process, pthreads, stack
Solution
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
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
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);
I.e. default-initialize a set of pthread attributes and ask for what stacksize the system gave you.
Problem
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? 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. Thread Function ``` #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); } ``` Main 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: 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