简体   繁体   English

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

[英]Relation between stack limit and threads

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

    Is <number of threads > * <each thread stack size > must be less than < stack size assigned by ulimit command > valid justification? <number of threads > * <each thread stack size >是否必须小于< stack size assigned by ulimit command >有效对齐?

  2. In the below program - each thread allocates char [PTHREAD_STACK_MIN] and 10 threads are created. 在下面的程序中 - 每个线程分配char [PTHREAD_STACK_MIN]并创建10个线程。 But when the ulimit is set to 10 * PTHREAD_STACK_MIN, it does not coredump due to abort. 但是当ulimit设置为10 * PTHREAD_STACK_MIN时,它不会因中止而进行coredump。 For some random value of stacksize (much less than 10 * PTHREAD_STACK_MIN), it core dumps. 对于stacksize的一些随机值(远小于10 * PTHREAD_STACK_MIN),它进行核心转储。 Why so? 为什么这样?

My Understanding is that stacksize represents the stack occupied by all the threads in summation for the process. 我的理解是stacksize表示进程总和中所有线程占用的堆栈。

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: PS:
I am using Ubuntu 10.04 LTS version, with below specification. 我正在使用Ubuntu 10.04 LTS版本,具有以下规格。
Linux laptop 2.6.32-26-generic #48-Ubuntu SMP Wed Nov 24 10:14:11 UTC 2010 x86_64 GNU/Linux Linux笔记本电脑2.6.32-26-通用#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. 在UNIX / Linux上, getrlimit(RLIMIT_STACK)仅保证给出主线程堆栈的大小。 The OpenGroup's reference is explicit on that, "initial thread's stack": OpenGroup的引用是明确的,“初始线程的堆栈”:

http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html 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): 对于Linux,有一个引用指示RLIMIT_STACK是默认情况下将用于任何线程堆栈的内容(对于NPTL线程):

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html 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. RLIMIT_ASRLIMIT_AS地址空间大小。
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) . 但是你确实可以创建线程数限制, sysconf(PTHREAD_THREADS_MAX) ,并且你确实有一个线程堆栈必须具有的最小大小的下限, sysconf(PTHREAD_STACK_MIN)

Also, you can query the default stacksize for new threads: 此外,您可以查询新线程的默认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);

Ie default-initialize a set of pthread attributes and ask for what stacksize the system gave you. 即默认初始化一组pthread属性,并询问系统给你的堆栈大小。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM