CodeZine(コードジン)

特集ページ一覧

pthreadについて(スタックサイズ)

スタックサイズの変更と、起動スレッド数の関係

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/01/18 14:00
目次

8. スレッド属性(サンプル)

8.3 サンプル

 前述しましたが、スタックサイズの最小値はPTHREAD_STACK_MINによって定義されています。しかし最大値は定義されていません。PTHREAD_STACK_MAXなどといったものはありません。

 これはつまり、環境によってスタックサイズが変わる事を意味していると思われ、その環境における最大値を認識してからスタックサイズを変更した方が良いでしょう。

 以下のサンプルプログラムは初期値と最小値のスタックサイズを取り出し、初期値に数値を掛け合わせた値をスタックサイズにしてスレッドを実行し、実行可能最大数を割り出しています。また、pthread_attr_setstackを使用し、ヒープから確保したメモリをスレッドのスタックとして利用しています。

 私の環境ではプログラムにGNU固有の拡張を有効にする必要がありました(#define _GNU_SOURCEの一文を追記します)。

stack_addr.c
/* gcc stackaddr.c -o stackaddr -W -Wall -g -lpthread */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <limits.h>
void * thread_func1( void * arg );
void * thread_func2( void * arg );

int main( ) {
    pthread_t           thread_id;
    pthread_attr_t      thread_attr;
    size_t              stack_size = 0;
    size_t              guard_size = 0;
    char *              thread_stack = 0;
    int                 mul = 0;
    int                 status = 0;

    pthread_attr_init( &thread_attr );
    pthread_attr_getstacksize( &thread_attr, &stack_size );
    pthread_attr_getguardsize( &thread_attr, &guard_size );
    printf( "Default stack size %zd[%zdM]; guard size %zd "
        "minimum is %u[%uK]\n",
        stack_size, stack_size >> 20, guard_size,
        PTHREAD_STACK_MIN, PTHREAD_STACK_MIN >> 10 );

    for( mul = 1;; mul ++ ) {
        status = pthread_attr_setstacksize(
            &thread_attr, stack_size * mul );
        if( status ) {
            printf( "pthread_attr_setstacksize:[%d][%s]\n",
                status, strerror( status ));
            break;
        }
        status = pthread_create( &thread_id, &thread_attr,
            thread_func1, 0 );
        if( status ) {
            printf( "set stack size  is %zd [%zdM] "
                "pthread_create error. [%d][%s]\n",
                stack_size * mul, stack_size * mul >> 20,
                status, strerror( status ));
            break;
        }
        pthread_join( thread_id, 0 );
    }

    for( mul = 1;; mul ++ ) {
        thread_stack = malloc( stack_size * mul );
        if( thread_stack == 0 ) {
            printf( "memory allocate is %zd [%zdM] "
                "malloc error. [%d][%s]\n",
                stack_size * mul, stack_size * mul >> 20,
                errno, strerror( errno ));
            break;
        }
        status = pthread_attr_setstack( &thread_attr,
            ( void * )thread_stack, stack_size );
        if( status ) {
            printf( "pthread_attr_setstacksize:[%d][%s]\n",
                status, strerror( status ));
            break;
        }
        status = pthread_create( &thread_id, &thread_attr,
            thread_func1, ( void * )&stack_size );
        if( status ) {
            printf( "pthread_create:[%d][%s]\n",
                status, strerror( status ));
            break;
        }
        pthread_join( thread_id, 0 );
        free( thread_stack );
    }

    pthread_attr_init( &thread_attr );
    pthread_attr_setstacksize( &thread_attr, stack_size );
    pthread_create( &thread_id, &thread_attr, thread_func2, 0 );
    pthread_join( thread_id, 0 );

    thread_stack = malloc( stack_size );
    pthread_attr_setstack(
        &thread_attr, ( void * )thread_stack, stack_size );
    pthread_create( &thread_id, &thread_attr, thread_func2, 0 );
    pthread_join( thread_id, 0 );

    return 0;
}

void * thread_func1( void * arg ) {
    ( void )arg;
    return arg;
}

void * thread_func2( void * arg ) {
    ( void )arg;
    char tmp[0];
    printf( "inner thread : [%p]\n", tmp );
    return 0;
}

 私の環境では、下記の通りとなりました。

guest $ ./stack_addr
Default stack size 10485760[10M]; guard size 4096 minimum is 
16384[16k]
set stack size  is 2023751680 [1930M] pthread_create error. 
[12][Cannot allocate memory]
memory allocate is 2023751680 [1930M] malloc error. 
[12][Cannot allocate memory]
inner thread : [0xb7dff3c8]
inner thread : [0xb73fd3c8]
guest $

 上記から、デフォルトスタックサイズは10M、最小スタックサイズは16Kです。最大スタックサイズは1.9G。ヒープも同値となります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:pthreadについて

もっと読む

著者プロフィール

  • 赤松 エイト(エイト)

    (株)DTSに勤てます。 WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。 mixiもやってまして、こちらは子育てとか日々の日記メインです。

あなたにオススメ

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5