Связь между пределом стека и потоками

  1. Какова связь между ulimit -s <значение > и размером стека (на уровне потока) в реализации Linux (или для это имеет значение для любой ОС)?

    Является ли <количество потоков > * <размер стека каждого потока > должен быть меньше <размер стека, назначенный командой ulimit > допустимое обоснование?

  2. В приведенной ниже программе - каждый поток выделяет char [PTHREAD_STACK_MIN] и Создано 10 потоков. Но когда ulimit установлен на 10 * PTHREAD_STACK_MIN, он не выполняет дамп памяти из-за прерывания. Для некоторого случайного значения stacksize (намного меньше 10 * PTHREAD_STACK_MIN) происходит дамп ядра. Почему?

Насколько я понимаю, размер стека представляет собой стек, занятый всеми потоками в сумме для процесса.

Функция потока

#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:
допустимое обоснование?

  • В приведенной ниже программе каждый поток выделяет char [PTHREAD_STACK_MIN], и создается 10 потоков. Но когда ulimit установлен на 10 * PTHREAD_STACK_MIN, он не выполняет дамп памяти из-за прерывания. Для некоторого случайного значения stacksize (намного меньше 10 * PTHREAD_STACK_MIN) происходит дамп ядра. Почему?

  • Насколько я понимаю, размер стека представляет собой стек, занимаемый всеми потоками в сумме для процесса.

    Функция потока

    #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:
    допустимое обоснование?

  • В приведенной ниже программе каждый поток выделяет char [PTHREAD_STACK_MIN], и создается 10 потоков. Но когда ulimit установлен на 10 * PTHREAD_STACK_MIN, он не выполняет дамп памяти из-за прерывания. Для некоторого случайного значения stacksize (намного меньше 10 * PTHREAD_STACK_MIN) происходит дамп ядра. Почему?

  • Насколько я понимаю, размер стека представляет собой стек, занимаемый всеми потоками в сумме для процесса.

    Функция потока

    #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-generic # 48-Ubuntu SMP Среда, 24 ноября, 10:14:11 UTC 2010 x86_64 GNU / Linux

    6
    задан kumar_m_kiran 6 December 2010 в 17:17
    поделиться