[解決済み] C++ 11 - condition_variable - wait_until が期待通りに動作しない。
2022-02-08 01:37:29
質問
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は、"Done"の前に"Timeout occurred"を表示しているので期待通りに動いていますが、sampleFunctionCondはそうではありません。wait_untilがタイムアウトしたことは知っていますが、関数sampleFunctionCOndが実行を終了した後にメッセージを表示しています。
どなたか、このことを理解する手助けをしていただけませんか?ありがとうございます。
どのように解決するのですか?
にはレースコンディションが存在します。
statusF2=cv.wait_until(...);
ステートメントを使用します。待ち時間がタイムアウトして、戻ろうとすることがあります。戻るには、ミューテックスを再取得する必要があります。同時に、他のスレッドがミューテックスを取得しました。そこで
statusF2=cv.wait_until(...);
は、他のスレッドが
flagValue
を true に設定し、ミューテックスを解放します。
このコードを修正するために
flagValue
は、待ち時間がタイムアウトしたかどうかをチェックする前にチェックする必要があります。
関連
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】C++の余分な資格エラー
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】coutはstdのメンバではない
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない