3

C++11でwait_forとwait_untilがどのように機能するかを理解するためのサンプルプログラムを実装しました。

コード-

#include <iostream>
#include <future>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <thread>

using namespace std;
using namespace std::chrono;

condition_variable cv;
mutex m;
bool flagValue=false;

int sampleFunction(int a)
{
    cout<<"Executing sampleFunction...";
    cout.flush();
    this_thread::sleep_for(seconds(5));
    cout<<"Done."<<endl;
    return a;
}

void sampleFunctionCond(int a)
{
    lock_guard<mutex> lg(m);
    cout<<"Executing sampleFunctionCond...";
    cout.flush();
    this_thread::sleep_for(seconds(5));
    cout<<"Done."<<endl;
    cout<<"Value : "<<a<<endl;
    flagValue=true;
    cv.notify_one();
    return;
}

int main()
{
   unique_lock<mutex> ul(m);
   future<int> f1=async(launch::async,sampleFunction,10);
   future_status statusF1=f1.wait_for(seconds(1));
   if(statusF1==future_status::ready)
    cout<<"Future is ready"<<endl;
   else if (statusF1==future_status::timeout)
    cout<<"Timeout occurred"<<endl;
   else if (statusF1==future_status::deferred)
    cout<<"Task is deferred"<<endl;
   cout<<"Value : "<<f1.get()<<endl;

   cv_status statusF2;
   thread t1(sampleFunctionCond,20);
   t1.detach();
   while(!flagValue)
   {
       statusF2=cv.wait_until(ul,system_clock::now()+seconds(2));
       if(statusF2==cv_status::timeout)
       {
       cout<<"Timeout occurred."<<endl;
       break;
       }
       else
       {
       cout<<"Condition variable is ready or spurious wake up occurred."<<endl;
       }
   }
}

出力-

Executing sampleFunction...Timeout occurred
Done.
Value : 10
Executing sampleFunctionCond...Done.
Value : 20
Timeout occurred.

sampleFunctionは、「完了」の前に「タイムアウトが発生しました」と出力されるため、期待どおりに機能していますが、sampleFunctionCondの場合はそうではありません。wait_untilがタイムアウトしたことはわかっていますが、関数sampleFunctionCOndの実行が終了した後にメッセージを出力します。

誰かが私がこれを理解するのを手伝ってくれますか?ありがとう。

4

2 に答える 2

4

statusF2=cv.wait_until(...);ステートメントに競合状態があります。何が起こるかというと、待機がタイムアウトになり、もうすぐ戻ってくるということです。戻すには、ミューテックスを再取得する必要があります。同時に、他のスレッドがミューテックスを取得しました。したがって、statusF2=cv.wait_until(...);他のスレッドがflagValuetrueに設定され、ミューテックスが解放されるまで戻ることはできません。

コードを修正するにはflagValue、待機がタイムアウトしたかどうかを確認する前に、の値を確認する必要があります。

于 2012-08-30T08:23:56.610 に答える
0

関数「sampleFunctionCond」は、ミューテックス「m」を常に保持するべきではありません。「flagValue=true;」の行の直​​前で「m」をロックしてみてください。

于 2013-05-07T06:43:02.537 に答える