• 締切済み

【C++】boost threadについて

現在visual studio 2010 を使ってC++による開発を行っています。 使用しているライブラリのソースコードを読んでいたら下記のような行を見つけたのですが、 どういった内容なのか検討が付かず、困っています。 ↓部分的で申し訳ないのですが、下記のような関数が使用されていました。   "boost::thread::yield ();"の使用例とかが解れば何がしたいのか解るのではと思っています。 --------------------------------------------------------------------------------- CloudViewer_impl (const std::string& window_name) : window_name_ (window_name), has_cloud_ (false), quit_ (false) { viewer_thread_ = boost::thread (boost::ref (*this)); while (!viewer_) { boost::thread::yield (); } } --------------------------------------------------------------------------------- 参考になるかと思い、std::this_threadのyield関数を調べると下記のように説明されていました。 [yield 関数]   現在のスレッドが通常実行を継続がオペレーティング システムに他のスレッドを実行するように通知します。 boost::thread配下の関数ということで、threadの操作をするモノだということは解るのですが、 これまで、あまりthreadを触って来なかったこともあり、見当がつきません。 不躾な質問で申し訳ありませんが、簡単なサンプルでyieldの使い方、使い処など教えて頂ければ有難いです。

みんなの回答

回答No.1

スレッドには大きく3つの状態があります。 - waiting : 待機中 - ready : 動けるんだけどCPUが空いてないので待機中 - running : 実行中 (最大でもCPUの数だけ) で、yield() は 実行中のスレッド(this_thread)がCPUを明け渡し、 ready なスレッドに実行権を与えます。 これによって忙しいスレッドばかりがCPUを占有するのを回避するです。 yieldとは"譲る" って意味ね。 # yield()したとき、readyなスレッドがなかったときはそのままrunningを維持します。

関連するQ&A

  • boost::threadでのjoinについて

    スレッド用に作成したループ用関数を自前で終了させてからjoinをすると、thread::m_joinableがfalseになりjoinでassertが出ることがあります。 問題の処理を簡単なモデルで説明しますと、 bool g_finish(false); void thread_loop(void) {  while(true)  {   ...   if(g_finish) break;  } } int main(void) {  boost::thread th(thread_loop);  sleep(100000);  g_finish=true;  th.join(); // assert  return 0; } といった感じになります。実際にはスレッド管理クラスにおいて複数のス レッドが管理されています。 冗長ですが、このような処理をするときにjoinのときにm_joinableがfalse になりassertが出るという事態です。 どなたが知識をお持ちの方がおられましたらご教授願えれば幸いです。

  • [C++]boostのbindについて教えてください。

    boostのbindについて下記のサイトを参考にしたのですが、よくわからない箇所があります。 1. http://gimite.net/behind/boostsample.htm 2. http://www.kmonos.net/alang/boost/classes/bind.html 1.のサイトに下記のサンプルがあります(一部抜粋)。 struct Boo{  void f(int i, int j)   { std::cout<<"Sum is "<<(i+j)<<"."<<std::endl; } }; void main(){  Boo boo;  boost::function2<void, int, int> func;  func= boost::bind(&Boo::f, &boo, _1, _2); // boo.fを代入  func(13, 7); } とし、func(13,7)の出力結果を20としています。 こちらについては納得できました。 しかし、2のサイトのサンプルがよく分かりません。 こちらでは、boost()を関数の引数にしています。 bool is_ordered( int a, int b, int c ) { return a<=b && b<=c; } int main() {  // 7以上12以下の最初の要素を探す。  // is_orderedに定数をbindして(くくりつけて)、  // 「is_ordered(7,第一引数,12)」と等価な  // 関数オブジェクトを作っているわけです。 int arr[] = {1,2,3,4,5,6,7,8,9,10}; const int len = sizeof(arr) / sizeof(arr[0]); int* f = find_if( arr, arr+len, boost::bind(is_ordered, 7, _1, 12) ); cout << *f << endl;      return 0; } bind()が関数の引数として扱われている場合、_1にはどんな値が入るのでしょうか?(find_if()の第一引数「arr」を_1に代入?) どなたか教えてください。 よろしくお願いいたします。

  • スレッドの優先順位に関して

    ただ今、黒本(徹底攻略 Java2 プログラマ問題集 Platform5.0 対応) を使用しSJC-Pの勉強をしているんですが、スレッドの20番目の問題が どうしてもわからないので質問させて下さい。 下記の問題なんですが コンパイルし実行した結果として正しい物を選ぶという 問題で、答えは「 B A B A B A と表示される」になります。 class MyThread extends Thread{ MyThread(String name){ super(name); } public void run(){ System.out.println(getName()); for(int i=0;i<2;i++){ try{ sleep(1000); }catch(Exception e){} yield(); System.out.println(getName()); }}} class T20{ public static void main(String[] args){ Thread t1 = new MyThread("A"); t1.setPriority(1); t1.start(); Thread t2 = new MyThread("B"); t2.setPriority(10); t2.start(); } } この問題の答えの解説で 優先順位を指定すると必ず高い優先順位のスレッドから 実行が開始するみたいな事が書かれてて、おかしいと思い、 検証してみたところ、私の環境では、結果が何通りも表示されました。 yield()についても私の持っている別の参考書には 「現在実行中のスレッドオブジェクトを実行可能状態に戻し、 他のスレッドに実行できるようにする。ただし優先順位の関係で実行中だったスレッドが再度実行される可能性もある。」 と書かれていて上記の答えに納得が出来ていません。 スレッドの優先順位とyieldに関して お手数ですが、アドバイスよろしくお願いします。

    • ベストアンサー
    • Java
  • boost::serializationについて

    次のコードがテンプレート辺りでコンパイルできません #include <list> #include <array> #include <fstream> #include <boost/serialization/serialization.hpp> #include <boost/serialization/array.hpp> #include <boost/serialization/list.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> std::list<std::array<bool, 3>> lab; std::array<bool, 3> pusharray; pusharray[0] = true; pusharray[1] = false; pusharray[2] = true; lab.push_back(pusharray); lab.push_back(pusharray); std::ofstream ofs("test"); boost::archive::binary_oarchive boa(ofs); boa << lab; ofs.close(); std::ifstream ifs("test"); boost::archive::binary_iarchive bia(ifs); bia >> lab; ifs.close(); エラーメッセージ: c:\program files\microsoft visual studio 10.0\vc\include\boost\archive\basic_binary_iprimitive.hpp(181): warning C4244: '引数' : 'std::streamsize' から 'size_t' への変換です。データが失われる可能性があります。 c:\program files\microsoft visual studio 10.0\vc\include\boost\archive\basic_binary_iprimitive.hpp(152): クラス テンプレート のメンバー関数 'void boost::archive::basic_binary_iprimitive<Archive,Elem,Tr>::load_binary(void *,size_t)' のコンパイル中 with [ Archive=boost::archive::naked_binary_iarchive, Elem=char, Tr=std::char_traits<char> ] c:\program files\microsoft visual studio 10.0\vc\include\boost\archive\detail\iserializer.hpp(362) : コンパイルされたクラスの テンプレート のインスタンス化 'void boost::archive::load_access::load_primitive<Archive,T>(Archive &,T &)' の参照を確認してください with [ Archive=boost::archive::naked_binary_iarchive, T=boost::archive::object_id_type ] (略) そもそもSTLコンテナのネストはserializeできないのでしょうか それともヘッダが足りないのでしょうか

  • C# スレッド終了の監視について

    お世話になります。 C#2005でプログラムを作成しております。 マルチスレッドでの、スレッドの終了の監視のことでご質問させていただきます。 下記のコードを実行すると、問題なく実行されます。 ------------------------------------------------------------------------------------ private int SetDataTreeView() { Thread RcvSetThread = new Thread(new ThreadStart(this.RcvDataSet)); RcvSetThread.Start(); } delegate void RcvDataSetDelegate(); void RcvDataGridSet() { /* フォーム内のDatagidviewへの値の代入 */ } void RcvDataSet() { Invoke(new RcvDataSetDelegate(RcvDataGridSet)); } ------------------------------------------------------------------------------------ このスレッドの終了を監視したく、下記のコードを追加してデバッグしてみましたが、 スレッドが実行されませんでした。 ------------------------------------------------------------------------------------ int isRcvSearchFlg = 0; private int SetDataTreeView() { Thread RcvSetThread = new Thread(new ThreadStart(this.RcvDataSet)); RcvSetThread.Start(); // スレッドが終了するまで待機する for (; ; ) { if (isRcvSearchFlg == 1) { break; } } } delegate void RcvDataSetDelegate(); void RcvDataGridSet() { /* フォーム内のDatagidviewへの値の代入 */ isRcvSearchFlg = 1; } void RcvDataSet() { Invoke(new RcvDataSetDelegate(RcvDataGridSet)); } ------------------------------------------------------------------------------------ また、以下も試してみましたが、結果は同じでした。 ------------------------------------------------------------------------------------ private int SetDataTreeView() { Thread RcvSetThread = new Thread(new ThreadStart(this.RcvDataSet)); RcvSetThread.Start(); // スレッドが終了するまで待機する RcvSetThread.Join(); } delegate void RcvDataSetDelegate(); void RcvDataGridSet() { /* フォーム内のDatagidviewへの値の代入処理 */ } void RcvDataSet() { Invoke(new RcvDataSetDelegate(RcvDataGridSet)); } ------------------------------------------------------------------------------------ スレッドの終了を監視する方法がわからず困っております。 お手数ですが、ご教授いただきたくよろしくお願い申し上げます。

  • スレッド

    VC++2008ExpressEditionを使用してプログラムを作成しています。 Windowsフォームアプリケーションを作成し、そこに、TextBoxとButtonを放り込み、ボタンを押すと以下のようなコードが実行されるようにしました。 関数testfuncはhoge::Form1::testfuncという風な場所で定義されています。 logBoxは、Form1のコンストラクタのTODOの部分で作成しています。   public: static System::Windows::Forms::TextBox^ logBox;   void testfunc(){     int i;     for(i=0;i<200;i++){       int t=clock();       while(10>clock()-t);       logBox+=L"aaraeaewa"+i+L"\r\n";       logBox->SelectionStart = logBox->Text->Length;       logBox->ScrollToCaret();     }   }   System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {     button1->Enabled=false;     button1->Text=L"実行中";     button1->Update();     ThreadStart^ trddel=gcnew ThreadStart(this,&hoge::Form1::testfunc);     Thread ^trd=gcnew Thread(trddel);     trd->Start();     button1->Enabled=true;     button1->Text=L"実行";   } この関数をボタンを押して実行すると、testfunc関数の logBox->SelectionStart = logBox->Text->Length; の部分で、 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。 追加情報: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'logBox' がアクセスされました。 という風なエラーが出ます。 読んだ感じだと、元々のスレッドで作成したコントロールを新しく作ったスレッドからコントロールすることは出来ないって感じのことが書かれているのですが、どの様にすればこれは回避できるようになるのでしょうか?

  • VC++2005のスレッド使用方法について

    現在、VC++2005 SP2にてDLLを作成しています。 DLLには一つスレッドがあり、開始関数が実行されれば、スレッドが起動。終了関数を実行すればスレッドを停止させたいと思っております。 関数を分けていますので、以下の内容をグローバルで宣言したいと考えています。 Thread^ oThread = gcnew Thread( gcnew ThreadStart( &CUart::ThreadProc ) );                                     ~~~~~~~~~~~~~~~~~~~~~~~~                                         実行関数です。 oThread->Start();  //開始関数のスレッド開始  oThread->Abort();  //終了関数のスレッド停止 現在、宣言をグローバルのところに配置して、ビルドすると エラー 1 error C3145: 'oThread' : グローバルまたは静的変数は、マネージ型 'System::Threading::Thread ^' を含むことはできません とエラーが発生してしまいます。 いろいろ調べましたが、なかなか進んでいない状態です。 使用方法が間違っているのでしょうか?申し訳ありませんが、教えてください。 もし、別の方法があればご教授願います。 よろしくお願いします。

  • スレッドについての質問です。

    下記のロジックを見ていただきたいのです。 スレッドがnullの間はrunが動いています。 問題は一番下に記載した"stopplay()"というメソッドだと思われます、スレッドを停止して直ぐにまた動かしていますがどうもスレッドが二つ動いている様子です。なぜでしょうか? ************************************************** //最初にスレッドを開始します。 public init(){ play(); } ************************************************** //スレッドのON OFF public void threadOnOff(boolean sw) { if(sw == true){ thread =new Thread(this); thread.start(); } else { thread = null; } } ************************************************** //スレッド開始 public void play(){ threadOnOff(true); } ************************************************** //スレッド停止 public void stop(){ threadOnOff(false); } ************************************************** //runメソッド  public void run(){ String mode = ""; while(thread != null){ try { thread.sleep(500); //0.5秒間隔で動きます。 mode = modeRequest(); if(mode.startsWith("STOP") == true) { //スレッド停止 threadOnOff(false); } } catch (InterruptedException ie) {} } } ************************************************** //問題のメソッドです。 public void stopplay(){ stop(); play(); }

    • ベストアンサー
    • Java
  • Ready Boostの効果について・・・

    PC初心者です。使用機種は下記です。 FMV-BIBILO NF40X OS:Windows Vista Home Premium CPU:Celeron M プロセッサー 520 CPU動作周波数(MHz):1600 メモリ:1G ネットにてUSBメモリのReady Boost機能について知り、Ready Boost対応のUSBメモリ:Cruzer Colors+ 2GB(メーカー名→San Disk:ヤマダ電機にて3080円)を購入しました。 そして、Ready Boostの設定を行いましたが、効果があまり感じられませんでした。 そこで、Ready Boostの設定の有無でのタスクマネージャの各種数値を見比べましたがよく分かりません。 下記に、その数値を記載しました。はたして、この数値的にReady Boost機能は効果的に働いていますでしょうか? 御教授お願いいたします。 Ready Boost設定時(推奨値1860で設定) メモリ604MB 物理メモリ 合計1013 キャッシュ済み534 空きメモリ3 カーネルメモリ 合計150 ページ59 非ページ90 システム ハンドル15942 スレッド680 プロセス70 ページ ファイル756M/2281M Ready Boostを設定していない各種数値 メモリ530MB 物理メモリ 合計1013 キャッシュ済み609 空きメモリ11 カーネルメモリ 合計115 ページ57 非ページ58 システム ハンドル15838 スレッド686 プロセス70 ページ ファイル712M/2281M ※上記数値は任意にタスクマネージャを開いたときの数値です。

  • C++におけるスレッド制御に関して

    C++初心者です。 スレッド制御の勉強をしておりますが、 なかなかうまくいきません。 下記のソースのようにスレッド生成をしておりますが、 スレッド用メソッドには、*を付けて使用するしか方法はないのでしょうか? pthread_createに渡す第3パラメータをメソッド名のみにして、呼ばれ元のメソッドの戻り値をvoid* ではなく、void のみで実施したいと思っておりますが、方法がわかりません。 大変申し訳ございませんが、ご教授よろしくお願いいたします。 ############################################################## # pthread_test.cc ############################################################## #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> /* * スレッドパラメータ格納用 */ typedef struct {  char printVal;  int interval; } ThreadParamT; // スレッドイニシャル関数 void *ThreadTest(void *arg) {  ThreadParamT *thread_test_param =(ThreadParamT*)arg;  while(1) {   fprintf(stderr,"%c", thread_test_param->printVal);   sleep(thread_test_param->interval);  }  return NULL; } int main(int argc,char *argv[]) {  int status;  // スレッドのパラメータ  pthread_t thread_test;  ThreadParamT thread_test_param;  thread_test_param.printVal = 'a';  thread_test_param.interval = 1;  // スレッドを生成  status=pthread_create(&thread_test, NULL, ThreadTest, &thread_test_param);  if(status!=0){   fprintf(stderr,"ERR! OUT!\n");   exit(1);  }  // 10s間待つ  sleep(10);  fprintf(stderr, "\n");  return 0; } ##############################################################