2010-12-06 32 views
5
  1. ulimit -s <value>とLinux実装のスタックサイズ(スレッドレベル)との関係はどのようなものですか?スタック制限とスレッドの関係

    <number of threads> * <each thread stack size>有効な正当な理由はありませんか?

  2. 以下のプログラムでは、各スレッドがchar [PTHREAD_STACK_MIN]を割り当て、10個のスレッドが作成されます。しかし、ulimitが10 * PTHREAD_STACK_MINに設定されている場合は、打ち切りのためにコアダンプしません。 stacksize(10 * PTHREAD_STACK_MINよりもはるかに小さい)のランダムな値に対しては、コアダンプが発生します。なぜそうなのか?

My Understandingは、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水曜日11月24日午前10時14分11秒UTC 2010 x86_64のGNU/Linuxの

答えて

5

UNIX/Linuxでは、getrlimit(RLIMIT_STACK)はメインスレッドのスタックのサイズを保証しています。 OpenGroupの参照は、「初期スレッドのスタック」、その上で明示的である:Linuxの場合

http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html

RLIMIT_STACKは(NPTLは、スレッドのための)任意のスレッド・スタック用にデフォルトで使用されるものであることを示す基準があります:プログラマはスタックを置くために、および/または新しいスレッドのためにどれだけのスタックを使用する場所(スレッドを作成するときに、非標準の属性を使用することにより)決定することができますので、

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html

一般的に、そのようなものとしてはありませんa "累積プロセススタック制限"むしろアドレス空間サイズの合計であるRLIMIT_ASから出てきます。
しかし、作成できるスレッド数には、sysconf(PTHREAD_THREADS_MAX)があり、スレッドスタックに必要な最小サイズの下限値はsysconf(PTHREAD_STACK_MIN)です。

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

すなわち:

また、あなたは新しいスレッドのデフォルトのスタックサイズを照会することができますデフォルト - pthread属性のセットを初期化し、システムがあなたに与えたスタックサイズを尋ねます。

+0

[Stack Clash](http://www.openwall.com/lists/oss-security/2017/06/19/1)修正後に 'rlimit_stack'を設定しようとすると、失敗や関連する問題が発生する可能性があります。 Red Hat [Issue 1463241](https://bugzilla.redhat.com/show_bug.cgi?id=1463241)も参照してください。 – jww

-1

スレッド化プログラムでは、(最初​​の1を除く)すべてのスレッドのためのスタックされていますヒープから割り当てられているので、RLIMIT_STACKはスレッドにどれくらいのスタックスペースを使用できるかとほとんど関係がありません。

+0

実際には、スタックは 'mmap(...、MAP_ANON | MAP_PRIVATE、...) 'によってデフォルトで割り当てられるUN * X上にあり、従ってアドレス空間の非結合部分は通常の(連続したsbrkを介して成長させた)プロセスヒープ。 'pthread_create()'を呼び出す前に適切に初期化された値で 'pthread_attr_t'を手動で作成すると、オプションでスレッドスタックをヒープに入れることもできますが、危険です - スタックオーバーフローは、通常、スタックの底部にマップされていないレッドゾーンを表示します。 –

+0

@FrankHはい、そうです。私は「ヒープ」をあまりにもゆるく使っていました。 –

関連する問題