スタックスペースが不足しているSolarisにプログラムがあります。
この問題を調査しながら、スタックのulimitが何であるかを簡単に調べました。
user@solaris-box:~$ ulimit -a
...
stack size (kbytes, -s) 8192
したがって、スタックサイズは8MBに制限されます。しかし、これはプロセスの制限ですか?
私のプロセスに10個のスレッドがあり、各スレッドに819kしか許可されていない場合はどうなりますか? (またはこれらの組み合わせで最大8MiBまで可能ですか?)
これに関するドキュメントが見つかりません。
答え1
一般化する
メインスレッドの場合は呼び出す必要がありますsetrlimit()
(おそらくを使用してulimit
)。今後このプロセスは、より大きなスタックサイズが有効であることを確認するために開始されます。
プロセスが開始されたスレッドの場合は使用する必要があります。pthread_attr_setstacksize()
スレッドスタックサイズは、stack size
/のリソース制限にまったく影響されないためです。setrlimit()
getrlimit()
コードは次のようになります。
pthread_attr attr;
pthread_attr_init( &attr );
// 32MB stack size example - should **NOT** hardcode this
// but get it from an environment variable or property setting
size_t stacksize = 32UL * 1024UL * 1024UL;
pthread_attr_setstacksize( &attr, stacksize );
pthread_create( &tid, &attr, start_func, thread_arg );
現在のスタックサイズ制限からスレッドスタックサイズを取得できます。
struct rlimit limits;
getrlimit( RLIMIT_STACK, &limits );
size_t stacksize = limits.rlim_cur; // use rlim_max for hard limit
(独自のスレッドを生成するライブラリを使用している場合、そのライブラリにはOpenMPIなどのスレッドスタックサイズを設定する文書化された独自の方法があります。)
詳細な回答
リソース制限はコマンドラインで設定されます。ulimit
ユーティリティ。
走るtruss -f -a -vall -o /tmp/truss.out /usr/bin/ulimit -a
と見える
address space limit (kbytes) (-M) unlimited
core file size (blocks) (-c) unlimited
cpu time (seconds) (-t) unlimited
data size (kbytes) (-d) unlimited
file size (blocks) (-f) unlimited
locks (-x) not supported
locked address space (kbytes) (-l) not supported
message queue size (kbytes) (-q) not supported
nice (-e) not supported
nofile (-n) 1024
nproc (-u) 29995
pipe buffer size (bytes) (-p) 5120
max memory size (kbytes) (-m) not supported
rtprio (-r) not supported
socket buffer size (bytes) (-b) 5120
sigpend (-i) 128
stack size (kbytes) (-s) 8192
swap size (kbytes) (-w) not supported
threads (-T) not supported
process size (kbytes) (-v) unlimited
調べてみれば/tmp/truss.out
分かるだろう。
7752: execve("/usr/bin/ulimit", 0xFFFF80FFBFFFF9E8, 0xFFFF80FFBFFFFA00) argc = 2
7752: argv: /usr/bin/ulimit -a
7752: sysinfo(SI_MACHINE, "i86pc", 257) = 6
much deleted extraneous data (loading shared libraries, etc)...
7752: getrlimit(RLIMIT_VMEM, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_CORE, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_CPU, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_DATA, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_FSIZE, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_NOFILE, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = 1024 max = 65536
7752: sysconfig(_CONFIG_CHILD_MAX) = 29995
7752: pathconf("/", _PC_PIPE_BUF) = 5120
7752: pathconf("/", _PC_PIPE_BUF) = 5120
7752: sysconfig(_CONFIG_SIGQUEUE_MAX) = 128
7752: getrlimit(RLIMIT_STACK, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = 8388608 max = RLIM64_INFINITY
7752: getrlimit(RLIMIT_VMEM, 0xFFFF80FFBFFFD4B0) = 0
7752: cur = RLIM64_INFINITY max = RLIM64_INFINITY
7752: write(1, " a d d r e s s s p a c".., 942) = 942
ulimit
私たちは使用するのを見るgetrlimit()
(および)ライブラリsetrlimit()
機能リソース制限を取得または設定します。
すべてこのページgetrlimit()
setrlimit()
man
(太い部分を参照):
RLIMIT_STACK
プロセススタックの最大サイズ(バイト単位)。システムはこの制限を超えてスタックを自動的に増やしません。
プロセス内で
setrlimit()
スタックサイズの制限は増加しますが、現在のメモリセグメントはその増加を可能にするために移動されません。プロセススタックが限界まで増加できるようにするには新しいスタックサイズを使用するには、プロセスを実行する前に制限を変更する必要があります。。マルチスレッドプロセスでは
setrlimit()
呼び出しスレッドが基本スレッドでない場合、呼び出しスレッドのスタックサイズの制限には影響しません。。setrlimit()
forへの呼び出しはRLIMIT_STACK
メインスレッドのスタックにのみ影響し、メインスレッドでのみ行われる必要があります(存在する場合)。信号が
SIGSEGV
プロセスに送信されます。プロセスがSIGSEGVを維持または無視するか、キャプチャしているがSIGSEGV
まだ代替スタックの使用をスケジュールしていない場合(参考資料を参照sigaltstack(2)
)、処理は送信前にSIGSEGV
設定されます。SIG_DFL
したがって、メインスレッド以外のプロセスによって生成されたスレッドのスタックサイズは、RLIMIT_STACK
プロセスリソース制限の影響を受けません。電話する必要がありますsetrlimit()
今後より大きなスタックサイズ制限が実際に適用されることを確認するために、プロセスは親プロセスで開始されます。
作成された新しいスレッドは属性
pthread_create()
で指定されたスタックを使用し、stackaddr
スタックは属性で指定されたバイト数の間持続しますstacksize
。デフォルトでは、スタックサイズは32ビットプロセスの場合は1MB、64ビットプロセスの場合は2MBです(バラよりpthread_attr_setstacksize(3C)
)。プロパティの両方にデフォルト値が使用されている場合は、 32ビットプロセスの場合stackaddr
は少なくとも1 MB、64ビットプロセスの場合は2 MBの新しいスレッドのスタックが作成されます。 (カスタムスタックサイズの説明を参照してください)。stacksize
pthread_create()
...
ノート
...
ユーザーが指定したスタックサイズは値より大きくなければなりません
PTHREAD_STACK_MIN
。最小スタックサイズは、ユーザースレッド関数のスタックフレームに対応できない場合がありますstart_func
。スタックサイズが指定されている場合は、start_func
最小要件に加えて呼び出すことができる要件と機能も満たす必要があります。スレッドのランタイムスタック要件を決定することはしばしば困難です。
PTHREAD_STACK_MIN
.txtファイルを実行するために必要なスタックストレージ容量を指定しますNULL
start_func
。スタックストアのフルランタイム要件は、ランタイム接続を実行するために必要なリポジトリと、スレッドが呼び出すprintf()
ライブラリランタイムに必要なリポジトリの量によって異なります。このように保存されたパラメータはプログラムが実行されるまでは不明であるため、デフォルトのスタックを使用するのが最善です。ランタイム要件を知っている場合、またはデフォルトよりも大きいスタックを使用することを決定した場合は、直接指定することをお勧めします。