我已经实现了一个示例程序来了解在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(...);
语句。可能发生的情况是,等待已经超时,即将返回。为了返回,它需要重新获取mutex。同时,另一个线程也已经获取了mutex。所以。statusF2=cv.wait_until(...);
等到另一个线程设置好了才能回来 flagValue
的值为true,并释放了mutex。
为了修复代码,将 flagValue
必须在检查等待是否超时之前进行检查。
函数 "sampleFunctionCond "不应该一直保持mutex "m"。你可以尝试在 "flagValue=true; "这一行之前立即锁定 "m"。