40

私は C++11 のstd::threadライブラリに慣れようとしてきましたが、つまずきに行き着きました。

最初はposixスレッドのバックグラウンドから来ましたが、そのようなタスクを実行するための参照が見つからないように見えるため、構築前に std::thread のスタックサイズをどのように設定するのか疑問に思っていました.

pthreads を使用してスタック サイズを設定するには、次のようにします。

void* foo(void* arg);
.
.
.
.
pthread_attr_t attribute;
pthread_t thread;

pthread_attr_init(&attribute);
pthread_attr_setstacksize(&attribute,1024);
pthread_create(&thread,&attribute,foo,0);
pthread_join(thread,0);

std::threadを使用するときに似たようなものはありますか?

私は次のリファレンスを使用しています。

http://en.cppreference.com/w/cpp/thread

4

6 に答える 6

25

最初はposixスレッドのバックグラウンドから来ましたが、そのようなタスクを実行するための参照が見つからないように見えるため、構築前に std::thread のスタックサイズをどのように設定するのか疑問に思っていました.

できません。std::threadは標準化されているため、これをサポートしていませんstd::thread。また、C++ ではマシンにスタックが必要でなく、ましてや固定サイズのスタックも必要ありません。

pthreads は、サポートするハードウェアに関してより制限的であり、スレッドごとに一定のスタック サイズがあることを前提としています。(だから、これを設定することができます)

于 2012-12-14T02:27:55.290 に答える
19

Loki Astari が既に述べたように、デフォルト以外のスタック サイズが実際に必要になることは非常にまれであり、通常はミスか不適切なコーディングの結果です。

  • デフォルトのスタック サイズがニーズに対して大きすぎると感じ、それを減らしたい場合は、忘れてください。最近のすべての OS は現在、仮想メモリ / オンデマンド コミットを使用しています。つまり、ページにアクセスするまで、メモリは予約されているだけで、実際には割り当てられていません。スタック サイズを小さくしても、実際のメモリ フットプリントは減りません。

  • この動作が原因で、OS はデフォルトのスタック サイズを非常に大きな値に設定する余裕があります。たとえば、通常の Debian では、これは 8MB ( ulimit -s) であり、あらゆるニーズに十分対応できるはずです。あなたがまだその限界に達しているなら、私の最初の考えはあなたのコードが間違っているということです.

  • これらすべてにもかかわらず、本当にスタック サイズを変更する必要がある場合 (つまり、スタック サイズを小さくしても意味がないので、大きくする必要がある場合)、POSIX では、プログラムの開始時にいつでもsetrlimitを使用して、デフォルトのスタック サイズを大きくすることができます。確かにこれはすべてのスレッドに影響しますが、それを必要とするスレッドだけが実際に追加のメモリを使用します。

  • 大事なことを言い忘れましたが、公平を期すために、スタック サイズを減らすことが理にかなっているまれなケースを見ることができます: 32 ビット システムに大量のスレッドがある場合、それらは仮想アドレス空間 (実際のメモリではなく) を使い果たす可能性があります。ヒープに使用できる十分なアドレス空間がなくなるまで。繰り返しになりますが、ここではsetrlimitが役に立ちますが、より大きな仮想アドレス空間の恩恵を受けるために 64 ビット システムに移行することをお勧めします (また、プログラムがとにかく大きい場合は、追加の RAM もおそらく恩恵を受けるでしょう)。

于 2013-02-14T05:09:58.090 に答える
18

私もこの問題を調査しています。一部のアプリケーションでは、デフォルトのスタック サイズが適切ではありません。例: プログラムは、解決しようとしている特定の問題に応じて深層再帰を実行します。プログラムは多くのスレッドを作成する必要があり、メモリ消費が問題になります。

私が見つけた(部分的な)解決策/回避策の要約は次のとおりです。

分割スタックの目的は、必要に応じて自動的に拡張される非連続スタックを許可することです。これは、それぞれが小さなスタックから開始する複数のスレッドを実行し、プログラムの必要に応じてスタックを拡大および縮小できることを意味します。

備考: gold linker-fsplit-stackの使用を開始した後にのみ機能しました。clang++ もこのフラグをサポートするようです。試したバージョン (clang++ 3.3) は、フラグを使用してアプリケーションをコンパイルしようとするとクラッシュしました。-fsplit-stack

  • Linux では、ulimit -s <size>アプリケーションを開始する前に を実行してスタック サイズを設定します。sizeKbs 単位のスタック サイズです。注意: このコマンドunlimit -s unlimitedは、 で作成されたスレッドのサイズには影響しませんでしたstd::thread。を使用ulimit -s unlimitedした場合、メイン スレッドは大きくなる可能性がありますが、作成されたスレッドstd::threadのサイズはデフォルトのままでした。

  • Visual Studio を使用する Windows では、linker/STACKパラメーターを使用するか/STACKSIZE、モジュール定義ファイルで使用できます。これは、作成されたすべてのスレッドの既定のサイズです。詳細については、このリンクを参照してください。コマンドラインツールEDITBINを使用して、実行可能ファイルでこのパラメーターを変更することもできます。

  • mingw g++ を使用する Windows では、オプションを使用できます-Wl,--stack,<size>。何らかの理由で、cygwin g++ を使用している場合、このフラグはメイン スレッドのサイズにのみ影響します。

私にとってうまくいかなかったアプローチ:

  • ulimit -s <size>OSX上。メインスレッドのサイズのみに影響します。さらに、pthread スタック サイズの Mac OSX のデフォルトは 512kB です。

  • setrlimitLinux と OSX のメイン スレッドのサイズにのみ影響します。cygwin では、うまくいきませんでした。常にエラーが返されるようです。

OSX の場合、boost::thread代わりにを使用する唯一の方法のようstd::threadですが、標準に固執する場合、これは適切ではありません。将来、 g++ と clang++ が-fsplit-stackOSX でもサポートされることを願っています。

于 2013-12-10T18:47:45.220 に答える
16

スコット・マイヤーズの本Overview of the New C++(C++0x)でこれを見つけました。コメントとして投稿できないのでかなり長いので、これは役に立ちますか?

スレッド、ミューテックス、条件変数などの背後にあるプラットフォーム固有のハンドルを取得するための標準APIもあります。これらのハンドルは、スレッドの優先順位の設定、スタックサイズの設定などのメカニズムであると想定されています(スタックサイズの設定に関しては、 Anthony Williams氏は次のように述べています。「スタックサイズの設定をサポートするOSのうち、すべて異なる方法で実行されます。特定のプラットフォーム用にコーディングしている場合(native_handleを使用しても問題ないなど)、そのプラットフォームの機能を次のように使用できます。スタックを切り替えます。たとえば、POSIXではスタックの明示的な割り当てとともにmakecontextとswapcontextを使用でき、WindowsではFibersを使用できます。次に、プラットフォーム固有の機能(Linkerフラグなど)を使用して、デフォルトのスタックサイズを何かに設定できます。本当に小さい、次に、必要に応じてスタックをより大きなものに切り替えます。」)

于 2012-12-14T02:45:02.723 に答える
15

ちょうど今、自分でこれに対する答えを探していました。

std::thread はこれをサポートしていませんが、boost::thread はサポートしているようです。

特に、boost::thread::attributesを使用してこれを実現できます。

boost::thread::attributes attrs;
attrs.set_stack_size(4096*10);
boost::thread myThread(attrs, fooFunction, 42);
于 2013-11-09T01:06:52.603 に答える