Relation between stack limit and threads

  • 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 - %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:
    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


    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: %ldn", stacksize);
    

    Ie default-initialize a set of pthread attributes and ask for what stacksize the system gave you.


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

    链接地址: http://www.djcxy.com/p/80250.html

    上一篇: Java堆分配行为不同

    下一篇: 堆栈限制和线程之间的关系