pthreadのデフォルトのスタックサイズ


24

私が理解しているように、Linux上のpthreadのデフォルトのスタックサイズは16Kです。64ビットUbuntuのインストールで奇妙な結果が得られます。

$ ulimit -s
8192

また:

pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Thread stack size = %d bytes \n", stacksize);

Prints
    Thread stack size = 8388608 bytes

スタックサイズが「8388608」ではないと確信しています。何が間違っているのでしょうか?


7
と思います8388608 / 1024 = 8192
cuonglm

6
スレッドカーネルスタックごと16kを考えています。問題をユーザー空間のスタックメモリから完全に分離します。カーネルスタックはページングや遅延割り当てができず、物理メモリ内の連続したページである必要があるため、小さいです。 elinux.org/Kernel_Small_Stacks。i386では、特に32ビットのデフォルトで8kスタックの場合、合計スレッド数が非常に多いことが問題になる可能性があります。
ピーターコーデス

回答:


21
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

stacksize属性は、作成されたスレッドのスタック用に割り当てられた(バイト)最小スタックサイズを定義しなければなりません。

この例では、スタックサイズは8388608バイトに設定されています。これは、コマンドulimit -s So that matchから返される8MBに相当します。

pthread_create()説明から:

のLinux / x86-32、新しいスレッドのデフォルトのスタックサイズは2メガバイト。NPTLスレッド実装 では、プログラム開始時のRLIMIT_STACKソフトリソース制限に「無制限」以外の値がある場合、新しいスレッドのデフォルトスタックサイズが決定されます。使用pthread_attr_setstacksizeを(3)、スタックサイズ属性は、明示的にデフォルト以外のスタックサイズを得るためには、スレッドを作成するために使用される引数attrに設定することができます。

したがって、スレッドスタックサイズは、上記のset関数またはulimitシステムプロパティを使用して設定できます。参照している16kについては、どのプラットフォームでそれを見たか、および/またはこれにシステム制限が設定されているかどうかは明らかではありません。

参照してくださいpthread_createのページをして、ここで、この上でいくつかの興味深い例について。


47

実際、仮想スタックのサイズ 8388608バイト(8 MB)です。もちろん、これは正しくないと結論付けるのは自然です。これは、99%の確率で2、3 KBが必要なときに、すべてのスレッドがスタックで消費する途方もなく大きなメモリ量だからです。

良いニュースは、スレッドが実際に必要とする物理メモリの量のみを使用することです。これは、プロセッサでハードウェアメモリ管理ユニット(MMU)を使用することでOSが得る魔法の力の1つです。発生することは次のとおりです。

  1. OSは、スレッド用にMMUのページテーブルを設定することにより、スタックに8 MBの仮想メモリを割り当てます。これには、ページテーブルエントリのみを保持するためのRAMがほとんど必要ありません。

  2. スレッドが実行され、まだ物理ページが割り当てられていないスタック上の仮想アドレスにアクセスしようとすると、MMUによって「ページフォールト」と呼ばれるハードウェア例外がトリガーされます。

  3. CPUコアは、(独自のスタックを持つ)特権実行モードに切り替え、カーネル内でページフォールト例外ハンドラー関数を呼び出すことにより、ページフォールト例外に応答します。

  4. カーネルはその仮想メモリページに物理RAMのページを割り当て、ユーザー空間のスレッドに戻ります。

ユーザー空間のスレッドには、その作業は一切表示されません。その観点から、メモリがずっとそこにあるかのようにスタックを使用します。一方、スタックはスレッドのニーズを満たすために自動的に成長します(または成長しません)。

MMUは、今日のコンピューターシステムのハードウェアの重要な部分です。特に、システムの「魔法」の多くを担っているので、MMUの機能と、一般的な仮想メモリについてさらに学ぶことを強くお勧めします。また、アプリケーションがパフォーマンスに敏感であり、大量のデータを処理する場合、TLB(MMUのページテーブルキャッシュ)の仕組みと、TLBヒット率を最大化するためにデータまたはアルゴリズムを再構築する方法を理解する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.