Recently, I met a problem which is related with condition variable in C++. The code is shown below :
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
std::condition_variable cv;
std::mutex mutex;
int main(){
std::unique_lock<std::mutex> uniqueLock(mutex);
while (true)
{
if(cv.wait_for(uniqueLock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout)
{
std::cout << "has image" << std::endl;
}
else
{
std::cout<< "time out " << std::endl;
}
}
return 0;
}
The goal of this code is that : each time when condition variable is notified in another thread (cv.notify()), it show "has image " in the console, and if it can not be notified more than 1000 milliseconds, it shows "time out".
So the theoretical output of the above code is (because the condition variable is not notified) :
time out
time out
time out
time out
But when i execute this code in the Vs2015, I found that the output is strange:
has image
time out
has image
time out
time out
time out
has image
has image
time out
time out
time out
time out
time out
has image
has image
I would like to know why i have this output and how can i achieve my goal
Thanks !
I don't know what the cause of your error is (but there are some plausible explanations in the comments). However, one way to fix your issue is to use the other overload of wait_for, which includes a predicate.
It could look something like this (hasImage is just a bool here, replace it with something that makes sense for your needs - !imageStorage.empty() or similar):
while (true)
{
if (cv.wait_for(uniqueLock, std::chrono::milliseconds(1000), []() {return hasImage;}))
{
std::cout << "has image" << std::endl;
hasImage = false;
}
else
{
std::cout << "time out " << std::endl;
}
}
The pertinent point is that the predicate checks if there actually is a new image, and if there isn't then it should continue to wait.
One limitation with this method is that, if the predicate returns false (no image), then you don't know if the condition variable woke due to a spurious wakeup, a timeout, or if there actually was an image but another thread just took it away before this one woke up. But if that is something your design can handle, then this variation works very well.
Related
Consider the follow code:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
void func()
{
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
}
int main()
{
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
func();
std::cout << "stop " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
outputs:
start 18737230ms
stop 18738230ms
We can see that 1 seconds passes before func() returns. However there is no std::future stored from std::async(...); - i.e.: auto f = std::async(...)
This appears to work - but I am wandering what the mechanism is such that this works. If I have a std::future (auto f in my little example) then when it goes out of scope it tidies up the thread - i.e. waits for 1 second and then the thread is disposed of behind the scenes.
A further test:
int main() {
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop1 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
auto f = std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop2 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
gives:
start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed
So this shows that storing the future, means that the thread runs parallel. Not storing the future means the thread appears to have to run to completion - I guess this is because a temporary future is created and destroyed?
So my conclusion is that you can't just call std::async(...) without storing the std::future if you want it to run in parallel (which is the whole point) - even if you don't plan to use the future.
hmm... I think I have just talked myself into the answer! - but I am not 100% sure I have the reasoning correct - hopefully I have...
If the std::future is created via std::async, the destructor waits for end of the task. This does not mean that the task does not run in parallel - it just waits for the end of the task at the end of scope of variable. Yet it makes usage of std::async without storing a std::future a bit tricky and I would generally recommend storing the future somewhere to avoid nasty surprises. Take a look at page about std::future destructor (emphasis mine):
these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.
On an embedded platform I ran into the issue that when waiting on a condition until time_point<clock>::max(), the program enters a busy loop completely using a CPU.
The program I am running is:
#include <mutex>
#include <condition_variable>
#include <iostream>
int main() {
std::mutex mutex;
std::condition_variable condition;
using namespace std::chrono;
using clock = steady_clock;
for (;;) {
auto forever = time_point<clock>::max();
std::unique_lock<std::mutex> lock(mutex);
std::cout << "Now waiting" << std::endl;
condition.wait_until(lock, forever);
std::cout << "Now waking up" << std::endl;
}
return 0;
}
I was quite sure this is a bug, and running this on my host's compiler (g++ 4.7) the application behaved as I expected (blocking forever). When writing a bug report I wanted to attach an ideone sample demonstrating the issue, but ideone also runs into a busy loop:
http://ideone.com/XPy0Wn
Now I am unsure who is correct here. Is there a standard definition of how wait_until on a condition should behave when the second argument is time_point<clock>::max()?
You likely observe a (silly) conversion of steady clock to system clock time:
#include <chrono>
#include <iostream>
using namespace std::chrono;
time_t silly_steady_clock_to_time_t( steady_clock::time_point t )
{
return system_clock::to_time_t(system_clock::now()
+ (t - steady_clock::now()));
}
int main() {
auto system_time = system_clock::to_time_t(system_clock::now());
auto forever = time_point<steady_clock>::max();
auto forever_time = silly_steady_clock_to_time_t(forever);
std::cout << ctime(&forever_time) << '\n';
std::cout << ctime(&system_time) << '\n';
return 0;
}
Output:
Fri Jun 16 11:40:31 1724
Tue Sep 27 15:44:54 2016
Note: the steady forever_time is in the past.
A change of clock to using clock = system_clock; will fix the issue.
As mentioned in the comments, if you want to try to track it down, you should check the return type of the call to wait_until.
It can be either std::cv_status::timeout or std::cv_status::no_timeout.
By doing that, you'll be able to understand what's going on there.
As mentioned in the standard, the return type adheres to the following rules:
cv_status::timeout if the absolute timeout specified by abs_time expired, otherwise cv_status::no_timeout.
Moreover:
The function will unblock when signaled by a call to notify_one(), a call to notify_all(), expiration of the absolute timeout specified by abs_time, or spuriously.
Likely the last one is your case and it's unlikely a bug.
You should rather look for the reasons that give place to those spurious wakeups.
Suppose that I have the following code:
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <iostream>
int main()
{
boost::thread thd([]{ std::cout << "str \n"; });
boost::this_thread::sleep_for(boost::chrono::seconds(3));
if (thd.try_join_for(boost::chrono::nanoseconds(1)))
{
std::cout << "Finished \n";
}
else
{
std::cout << "Running \n";
}
}
MSVC-12.0 and boost 1.55 gives me the different output each time when I start this program. For example,
str
Finished
str
Finished
str
Running
When I change boost::chrono::nanoseconds to boost::chrono::microseconds the output is looks as expected.
Why? What am I doing wrong? Is it a bug in boost library? Is there a ticket about in in boost bug tracker?
Thanks in advance.
Your program simply has a race, most probably due to the fact that 1 nanosecond is awfully short.
try_join_for is implemented by calling try_join_until, a function that will attempt joining until a certain timepoint has been reached:
// I stripped some unrelated template stuff from the code
// to make it more readable
bool try_join_for(const chrono::duration& rel_time)
{
return try_join_until(chrono::steady_clock::now() + rel_time);
}
bool try_join_until(const chrono::time_point& t)
{
system_clock::time_point s_now = system_clock::now();
bool joined= false;
do {
Clock::duration d = ceil<nanoseconds>(t-Clock::now());
if (d <= Clock::duration::zero())
return false; // in case the Clock::time_point t is already reached
// only here we attempt to join for the first time:
joined = try_join_until(s_now + d);
} while (! joined);
return true;
}
The problem is now that try_join_until will check whether the requested time_point has been reached before attempting the join. As you can see, it needs to perform two other calls to clock::now() and some computation to compare the obtained values to the deadline given by the user. This may or may not be completed before the clock jumps beyond your given 1 nanosecond deadline, resulting in the unpredictability of the output.
Be aware that in general timing dependent code like this is fragile. Even with timeouts in the order of milliseconds, if you get preempted at a bad point during execution and there is a high load on the CPU, you might miss a deadline in rare cases. So be sure to always chose your deadlines carefully and never make assumptions that a deadline will be big enough in all possible cases.
What is wrong with just calling .join()? If you insist you can check before you join:
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <iostream>
int main()
{
boost::thread thd([]{ std::cout << "str\n"; });
boost::this_thread::sleep_for(boost::chrono::seconds(3));
if (thd.joinable())
thd.join();
}
Note that the behaviour is Undefined anyway if you fail to join a thread before program exit. Use
futures,
condition variables or
semaphores
to signal job completion if that's what you were trying to monitor.
i have a synchronize function that i want to test if it ends.
i want to be able to run code for X time, and if the time ends to continue.
here what i want:
bool flag = false;
some_function_that_run_the_next_block_for_x_sec()
{
my_sync_func_that_i_want_to_test();
flag = true;
}
Assert::IsTrue(flag);
is there a simple way to do this?
SynchronizationContext
thanks.
The link you posted gives me little insight on how that class would be used (maybe Microsoft is saving up bytes on sample code to pay for Ballmer's golden parachute next year?) so pardon me for completely ignoring it.
Something like this:
auto result = async(launch::async, my_sync_func_that_i_want_to_test);
future_status status = result.wait_for(chrono::milliseconds(100));
if (status == future_status::timeout)
cout << "Timed out" << endl;
if (status == future_status::ready)
cout << "Finished on time" << endl;
Need inclusion of the <future> and <chrono> headers.
If my_sync_func_that_i_want_to_test() never finishes you'll have another problem. The future object (result) will block until the thread launched by async() finishes. There's no portable way to recover from "killed/canceled/aborted" threads, so this will probably require some platform-specific code, even if you roll out your own async_that_detaches_the_thread() (which is not hard to find, here's one example).
I need to know how create a timer or measure out 500ms in C++ in a linux environment. I have tried using gettimeofday and using the time structure but cant get the correct precision for milliseconds. What I am trying to do is have an operation continue for a max of 500ms...after 500ms something else happens.
If you have access to C++11 then your best bet it to use std::chrono library
http://en.cppreference.com/w/cpp/chrono/duration
I aren't entirely sure what you want to do with it do you want to wait for exactly 500ms?
you can so this for that
std::this_thread::sleep_for(std::chrono::milliseconds(500));
you can do an operation until 500 milliseconds has elapsed by getting a time pointer and check to see whether timepoint - system_time::now() is greater than 500ms
//if you compiler supports it you can use auto
std::chrono::system_clock::time_point start=std::chrono::system_clock::now();
while(start-std::chrono::system_clock::now()
< std::chrono::milliseconds(500))
{
//do action
}
If you don't have C++11 this will also work with boost chrono library. The advantage of this approach is that it is portable unlike using linux time functions.
Your question isn't really clear about why you "can't get the correct precision" or what happens when you try to do that, but if you're having trouble with gettimeofday, consider using clock_gettime instead. man clock_gettime for details.
Since you are in Linux, you can use the system call usleep
int usleep(useconds_t usec);
Which will let your process sleep for some microseconds period.
#include <chrono>
#include <iostream>
#include <future>
#include <atomic>
void keep_busy(std::chrono::milliseconds this_long,std::atomic<bool> *canceled) {
auto start = std::chrono::high_resolution_clock::now();
while(std::chrono::high_resolution_clock::now() < start+this_long) {
std::cout << "work\n";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if(canceled->load()) {
std::cout << "canceling op\n";
throw "operation canceled";
}
}
}
int main() {
std::atomic<bool> canceled(false);
auto future = std::async(std::launch::async,
keep_busy,std::chrono::milliseconds(600),&canceled);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
canceled.store(true);
try {
future.get();
std::cout << "operation succeded\n";
} catch( char const *e) {
std::cout << "operation failed due to: " << e << '\n';
}
}
I'm not entirely sure this is correct...