質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Q&A

解決済

2回答

6476閲覧

CreateThreadで指定するスタックサイズ

awawa7

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

0グッド

0クリップ

投稿2016/08/08 08:50

CreateThread関数を使用して、スレッドを立ち上げる際に、第二引数でスタックサイズを指定した場合、その指定したスタックサイズをOSが変更(最適化?)してプログラムが動くということはあるのでしょうか?

例)
CreateThreadでスタックサイズ「4000」を指定
ただ、実際にそのスレッドのスタックサイズは「5000」だった

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2016/08/08 09:10

スタックサイズの確認はどのようにされたのでしょう?
awawa7

2016/08/09 23:51

ありがとうございます。 実際にスタックサイズを確認したわけではありませんが、そのスレッドで使用している関数で宣言している自動変数のサイズを確認したところ、CreateThreadで指定したスタックサイズよりも大きくなっていることが確認できました。
guest

回答2

0

ベストアンサー

あります。CreateThreadの説明にあるとおりスタックのサイズはメモリのページサイズの倍数に丸められるので指定したサイズにはならないです。
あとこれはあくまで初期サイズなので足りなくなったら自動的に拡大します。

投稿2016/08/08 10:17

toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

awawa7

2016/08/09 23:53

回答ありがとうございます。 >あくまで初期サイズなので足りなくなったら自動的に拡大します。 つまり、CreateThreadでスタックサイズを指定したとしても、それは意味が無いということでしょうか? 初歩的な質問で申し訳ありません。
toki_td

2016/08/12 05:33

いえ、この値は最初の確保するサイズを指定するのと同時に既定の最大サイズを増やす役割もあります。 Windowsではデフォルト(最小)で各スタックに1MBの仮想領域が割り当てられます。 ですので、CreateThreadで指定したサイズを超えても1MBまではOSが自動的に物理メモリの割り当てを拡大してくれますがそれ以上はどうやっても増えません。スタックオーバーフロー例外が発生してプログラムが終了します。 1MBよりも大きなスタックが必要な場合、あらかじめ大きな値を設定することでWindowsは割り当てる仮想領域を増やしてくれます。 CreateThreadの説明に > また、既定のスタックサイズを減らすことにより、さらに多くのスレッドを作成することもできます。 とありますが少なくともWindows10 Update2では1MB以下を指定しても1MB確保されたのでこれは嘘だと思います。メモリが小さかった昔は意味があってそうなってたかもしれませんが。
toki_td

2016/08/12 05:47

ちなみに、デフォルト1MBと書きましたがこの値はOSの規定値ではなくて実際にはプログラムの情報に含まれていてVSだとリンクの設定で変更できます。 最小はやはり1MBのようですが。
退会済みユーザー

退会済みユーザー

2016/08/19 13:17

横から失礼します。スタックが足りなくなったら自動的に拡大する、というのは初めて聞きましたが、どのようなときに拡大されますか? 関数をコールする際にスタックエリアが確保された後は、その関数を処理が抜けるまではスタックサイズは変更できないように思うのですが・・・ また、仮想領域とはなんでしょうか? スタックエリアとはどのような関係があるのでしょうか?
toki_td

2016/08/20 06:09

仮想記憶の一部の領域って意味で仮想領域と書きました。「仮想アドレス空間」の方が正しいのかな? スレッドが作成されたときプロセスの仮想記憶の一部をスタック領域として1MBなら1MB固定で割り当てられます。このサイズを変更する方法はありませんがWindowsは最低1MB割り当てるようです。この領域分使用可能なのでCreateThreadで100KB指定しても実際は1MBありますから、スレッドからしたら拡大しているように見えます。 物理メモリも割り当て分まとめて確保されるわけではなくスレッドが必要としたときに順次確保されていきます。 関数コールのスタックエリアは↑のスタック領域のうちその関数で使用している一部分の話になります。 関数の処理の途中でスタックエリアのサイズを変更できないこともないですよ。C言語でも(多くの実装では)スタックポインタをずらすalloca関数があるくらいですから。小さくなることはあまり実用性がないので普通ないですがアセンブラで書けば不可能ではないです。辻褄が合えばプログラムは動くので。
退会済みユーザー

退会済みユーザー

2016/08/20 11:37 編集

僕は使ったことがないのですが、allocaはスタックからメモリを確保するのであって、スタックのサイズを変更するのではないように思うのですが違いますか?(違いますね。下記追記参照) 勘違いしていることがありました。 ちょっと分かり難かったのは、スレッドがスタックとして使用できる全メモリ領域と、関数コール時に割り当てられる量の2種類があって、明確に区別する用語がないからかも知れません。前者をスタック予約領域、後者を単にスタックと言えばいいのでしょうかね? 少なくとも僕は勘違いしてしまいました。 スタック予約領域の使用済エリアが仮想エリアに待避されることがある、というのはまだ理解できますが、アクティブなスタックが仮想エリアに待避される状況が僕にはちょっと理解できなかったのです。理論的にはあり得るのかも知れませんが。 追記: ここまで書いてきて更なる勘違い?に気が付きました。関数コール時にその関数コールのために確保されるスタックのサイズに上限があるのかと思っていたのですが、どうもそういったサイズを指定するところが何処にもなさそうなので、そういうサイズはないと言うことでしょうか。つまり、上記のスレッドに割り当てられるスタック予約領域の空きエリアを超えない範囲であれば、1つの関数が確保できるスタックに上限は無いということです。 上記allocaはそのあると思っていた最大サイズを変更できない、と思っていたのです。
toki_td

2016/08/20 13:29

多分以下が混じっているんだと思います 1. OSが割り当てるスタックの領域   スタックとして使用可能な空間、増減不可 2. 物理メモリが割り当てれている領域   実際にデータを読み書きできる領域、OSが必要なら増やす   1のうち実際に使用されている部分 3. 関数が呼び出されたときに確保されるスタック領域   自動変数などとして使用、allocaで増やせる   2の領域のうち、関数が使用する部分 今回の質問は1, 2の話で、cafelasmさんは3の話をされているようです。 確かに用語が混じってしまいますね、、、 > アクティブなスタックが仮想エリアに待避される状況が僕にはちょっと理解できなかったのです この話は今回は特にしていないです。多分無いと思いますが > つまり、上記のスレッドに割り当てられるスタック予約領域の空きエリアを超えない > 範囲であれば、1つの関数が確保できるスタックに上限は無いということです。 はい、それであっていると思います。 関数が追加でメモリを必要になったらallocaでスタックに確保可能で最大サイズは現在のスタックポインタの位置から1のスレッドに割り当てられた領域の先頭までになります。
退会済みユーザー

退会済みユーザー

2016/08/21 00:08

toki_td さん、お手数おかけしました。まとめていただいてありがとうございます。
guest

0

すでに解決済みとはなっていますが、Windowsでスタック領域が仮想メモリ空間上にどのように確保されているかは、VMMapというツールを使用すれば、簡単に状況が掴めます。(スタック用にアドレス空間のみ確保されているか、実際にメモリが割り当てられているのかなども)

ご参考までに。

投稿2016/08/22 18:39

KenjiToriumi

総合スコア344

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問