0

私はブーストスレッドの使用にかなり慣れていません。私はほとんど何かを実行していますが、つまずきのブロックにぶつかりました:どんな助けもいただければ幸いです.

VC++ (VS2010 Windows フォーム) アプリケーションがあります。近い将来、これを C++ と Linux に移植する必要があるため、移植を「容易にする」ためにスレッドなどにブースト ライブラリを使用しています。

I/O を実行するクラスにワーカー関数があります。

void myClass::doIO{

    while (!boolKillthread){


    //do some work

    //sleep thread 
    boost::this_thread::sleep_for(boost::chrono::milliseconds(333));
    }
}

これはブーストスレッドで開始されます:

boost::thread m_MyThread;
m_MyThread = boost::thread(boost::bind(&myClass::doIO));

これは問題なく動作しており、I/O ポートはポーリングされており、親クラスに完全にコールバックしています。しかし:

いくつかの作業を実行するために doIO スレッドを待機する必要がある別の関数があるため、次の行にコードを含む関数があります。

while (myClass.IsWorkDone() == true){

    //hang a around a while

    //lines commented out below have been tried, but don't resolve the problem
    //boost::this_thread::yield();
    //boost::this_thread::sleep(boost::posix_time::milliseconds(50));
    //boost::this_thread::sleep_for(boost::chrono::milliseconds(50));

}

問題は、コードが while ループに入るとすぐに、ブースト スレッドの doIO が停止することです。まるでそれ自体のスレッドで実行されていないかのようです。上記のコメントアウトされた行に従ってスリープと利回りを挿入しようとしましたが、役に立ちませんでした。

何か案は?


すべての回答に感謝します:はい、(疑似コード)「IsWorkDone」は変数を返すだけなので、boost::mutex::scoped_lock を使用してその変数を更新することを理解しています(そして今試しました)。

bool myWorkIsDone = false;

bool myClass::IsWorkDone{ return myWorkIsDone; }



void myClass::doIO{

    while (!boolKillthread){


    //do some work
    if (SomeCondition){
        boost::mutex::scoped_lock lock(myMutex);
        myWorkIsDone = true;
    }

    //sleep thread 
    boost::this_thread::sleep_for(boost::chrono::milliseconds(333));
    }
}

それは問題ありませんが、要点は(明らかな何かが欠けていない限り、おそらくそうです)、メインコードがループ内にあるときにスレッドが実行されているようには見えないということです

while (myClass.IsWorkDone() == true){

    //hang a around a while

}

通常、IDE は doIO のブレークポイントで停止しますが、実行が上記の while ループにある場合は停止しません。

追加する (関連する) コードはこれ以上ありません。かなり単純なはずですが、機能しません。

4

1 に答える 1

2

どのようにIsWorkDone見えますか?次のように見えますか?

 bool IsWorkDone() const { return workdone_; }

もしそうなら、それはあなたの問題です。へのアクセスをラップするには、ミューテックスを使用する必要がありますworkdone_。これが共有状態であり、共有状態にはミューテックスが必要です。コンパイラはおそらくループの先頭で変数を読み取っており、再度読み取る必要はありません。結局のところ、それがわかる限り、変更する理由はまったくないので、もう一度読んでも意味がありません。

そして、それが再度読み取られたとしても、CPU にはそれを保持する適切なキャッシュ ラインがあり、おそらくフラッシュされることはないため、代わりにそれを読み取っているだけです。

ああ、それを設定するときは、ミューテックスも必要です。

にするの::std::atomic<bool>は実際にはより良いアイデアですが、まだそれを持っていないと思います。

于 2013-01-09T13:26:12.273 に答える