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

时间:2010-12-06 17:17:04

标签: c++ linux process stack pthreads

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

    <number of threads&gt; * <each thread stack size&gt;必须小于< stack size assigned by ulimit command&gt;有效的理由?

  2. 在下面的程序中 - 每个线程分配char [PTHREAD_STACK_MIN]并创建10个线程。但是当ulimit设置为10 * PTHREAD_STACK_MIN时,它不会因中止而进行coredump。对于stacksize的一些随机值(远小于10 * PTHREAD_STACK_MIN),它进行核心转储。为什么会这样?

  3. 我的理解是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 - %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

2 个答案:

答案 0 :(得分:6)

在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)

此外,您可以查询新线程的默认stacksize:

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);

即。 default-initialize一组pthread属性,并询问系统给你的堆栈大小。

答案 1 :(得分:-1)

在线程程序中,所有线程(初始线程除外)的堆栈都是从堆中分配的,因此RLIMIT_STACK与您可以为线程使用多少堆栈空间几乎没有关系。