Why does std::timed_mutex::try_lock_for not work? - c++

I used gcc-4.8.1(configure: ./configure --prefix=/usr/local) to compile following code in Ubuntu 12.04, but when I ran it, it didn't work. it didn't stop to wait the mutex. It returned false, and outputed "Hello world!"
command: g++ -std=c++11 main.cpp -omain -pthread
When I used gcc-4.6(apt-get install g++) to compile it, it worked well. The program waited about ten seconds, and outputed "Hello world!"
#include <thread>
#include <iostream>
#include <chrono>
#include <mutex>
std::timed_mutex test_mutex;
void f()
{
test_mutex.try_lock_for(std::chrono::seconds(10));
std::cout << "hello world\n";
}
int main()
{
std::lock_guard<std::timed_mutex> l(test_mutex);
std::thread t(f);
t.join();
return 0;
}

If I am not mistaken, that is Bug 54562 -mutex and condition variable timers.
The reason for the bug is also mentioned:
This is because it uses the CLOCK_MONOTONIC clock (if available on the
platform) to calculate the absolute time when it needs to return,
which is incorrect as the POSIX pthread_mutex_timedlock() call uses
the CLOCK_REALTIME clock, and on my platform the monotonic clock is
way behind the real time clock.
However, this doesn't explain why you see the correct behavior on gcc-4.6 though. Perhaps _GLIBCXX_USE_CLOCK_MONOTONIC is not enabled?

A possible workaround:
const int WAIT_PRECISION_MS = 10; // Change it to whatever you like
int TIME_TO_WAIT_MS = 2000; // Change it to whatever you like
int ms_waited = 0;
bool got_lock = false;
while (ms_waited < TIME_TO_WAIT_MS) {
std::this_thread::sleep_for(
std::chrono::milliseconds(WAIT_PRECISION_MS));
ms_waited += WAIT_PRECISION_MS;
got_lock = YOUR_MUTEX.try_lock();
if (got_lock) {
break;
}
}
The WAIT_PRECISION_MS will tell the while loop how often to "wake up" and try getting the lock. But, it would also tell how accurate your deadline is going to be, unless your precision time is a factor of the deadline time.
For example:
deadline = 20, precision = 3: 3 is not a factor of 20 - the last iteration of the while loop will be when ms_waited is 18. It means that you are going to wait a total of 21ms and not 20ms.
deadline = 20, precision = 4: 4 is a factor of 20 - the last iteration of the while loop will be when ms_waited is 16. It means that you are going to wait exactly 20ms, as your deadline is defined.

Related

Why does std::condition_variable::wait_for() return with timeout if duration too large?

The following behavior was seen under g++ 11.2.1 . The std::condition_variable wait_for method returns immediately if the timeout variable is too large. In particular in the program below, if num_years==1, then the program hangs waiting as expected (presumably for 1 year), but if the variable num_years==1000 then the program returns immediatly.
Why does this happen? Is this a bug in g++? And a related question, how do you make the cv.wait_for() wait indefinitely, instead of guessing a large timeout value?
// This is 'cv_wait.cc' compile with:
//
// g++ -o cv_wait -std=c++2a cv_wait.cc
//
// An example showing that wait_for() returns immediately with a timeout
// return value if the duration variable is "too large".
//
#include <iostream>
#include <condition_variable>
#include <chrono>
int main(int argc, char **argv)
{
std::condition_variable cv;
std::mutex cv_m;
// If num_years is "too large", e.g. 1000, then cv.wait_for()
// returns immediately with a timeout condition!
int num_years = 1; // If 1000 then cv.wait_for() returns immediately!
std::chrono::seconds timeout((uint64_t)3600 * 24 * 365 * num_years);
std::unique_lock<std::mutex> lock(cv_m);
if (cv.wait_for(lock, timeout, [] { return false; }))
std::cerr << "No timeout!\n";
else
std::cerr << "Timeout!\n";
}
This is an overflow bug under the hood of condition_variable::wait_for. Internally it is waiting using steady_clock which counts nanoseconds. This clock overflows at +/-292 years. So when 1000 years gets converted to nanoseconds, it is overflowing.
This looks like a standards bug as opposed to an implementation bug: http://eel.is/c++draft/thread.condition#condvar-24
The implementation should check for overflows of this type and in case found, just wait for the maximum time it is capable of waiting for.

What is the most efficient way to calling a function every n seconds in c++?

So I'm trying to call a function every n seconds. The below is a simple representation of what I'm trying to achieve. I wanted to know if the below method is the only way to achieve this. I would love if the "if" condition can be avoided.
#include <stdio.h>
#include <time.h>
void print_hello(int i) {
printf("hello\n");
printf("%d\n", i);
}
int main () {
time_t start_t, end_t;
double diff_t;
time(&start_t);
int i = 0;
while(1) {
time(&end_t);
// printf("here in main");
i = i + 1;
diff_t = difftime(end_t, start_t);
if(diff_t==5) {
// printf("Execution time = %f\n", diff_t);
print_hello(i);
time(&start_t);
}
}
return(0);
}
The usage of time in OPs program can be reduced to something like
// get tStart;
// set tEnd = tStart + x;
do {
// get t;
} while (t < tEnd);
This is what is called busy-wait.
It might be used to write code with most precise timing as well as in other special cases. The draw-back is that the waiting consumes ful CPU load. (You might be even able to hear this – by raising ventilation noise.)
In general, however, spinning is considered an anti-pattern and should be avoided, as processor time that could be used to execute a different task is instead wasted on useless activity.
Another option is to delegate the wake-up to the system, which reduces the load of process/thread to minimum while waiting:
#include <chrono>
#include <iostream>
#include <thread>
void print_hello(int i)
{
std::cout << "hello\n"
<< i << '\n';
}
int main ()
{
using namespace std::chrono_literals; // to support e.g. 5s for 5 sceconds
auto tStart = std::chrono::system_clock::now();
for (int i = 1; i <= 3; ++i) {
auto tEnd = tStart + 2s;
std::this_thread::sleep_until(tEnd);
print_hello(i);
tStart = tEnd;
}
}
Output:
hello
1
hello
2
hello
3
Live Demo on coliru
(I had to reduce number of iterations and the waiting times to prevent the TLE in online compiler.)
std::this_thread::sleep_until
Blocks the execution of the current thread until specified sleep_time has been reached.
The clock tied to sleep_time is used, which means that adjustments of the clock are taken into account. Thus, the duration of the block might, but might not, be less or more than sleep_time - Clock::now() at the time of the call, depending on the direction of the adjustment. The function also may block for longer than until after sleep_time has been reached due to scheduling or resource contention delays.
The last sentence mentions the draw-back of this solution: The OS may decide to wake-up the thread/process later than requested. That may happen e.g. is OS is under high load. In the “normal” case, the latency shouldn't be more than a few milli-seconds. So, the latency might be tolerable.
Please, note how tEnd and tStart are updated in loop. The current wake-up time is not considered to prevent accumulation of latencies.

std::thread does not start immediately as expected (c++11)

I have the following code in my main.cpp
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
doSomething(); // in the main Thread
t1.join();
I was expecting t1 to start immediately and start along the main thread.
However, this is not the case. I measure the execution time of my program, repeat this 100 times and make some plots.
See the peak in the following picture.
Now if I wait a bit after the creation of t1
std::this_thread::sleep_for(std::chrono::milliseconds(100));
I get better results. See the following picture.
(Still with a peak there, but well ..)
Obviously my questions are:
Why a peak?
Why I don't have a straight line?
EDIT
Ok, from the comments I understand by now, that there might be some scheduler magic going on.
Here is a working example
#include <thread>
#include <chrono>
#include <iostream>
#include <pthread.h>
#include <functional>
int main() {
float x = 0; float y = 0;
std::chrono::time_point<std::chrono::system_clock> start, stop;
start= std::chrono::system_clock::now();
auto Thread = std::thread([](){std::cout<<"Excuting thread"<<std::endl;});
stop = std::chrono::system_clock::now();
for(int i = 0 ; i<10000 ; i++)
y += x*x*x*x*x;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
Thread.join();
std::chrono::duration<double> elapsed_time = stop - start;
std::cout << "Taken time: " << std::to_string(elapsed_time.count()) << " "<< std::endl;
return 0;
}
Compiling:
g++-7 -lpthread threads.cpp -o out2.out
For Analysis I use this code
import subprocess
import matplotlib.pyplot as plt
import numpy as np
RUNS = 1000
factor = 1000
times = []
for i in range(RUNS):
p = subprocess.run(["./out2.out"], stdout=subprocess.PIPE)
line = p.stdout
times.append(float(line.split()[-1]))
print(i, RUNS)
times = np.array(times) * factor
plt.plot(times, "-")
plt.ylabel("time * %d" % factor)
plt.xlabel("#runs")
plt.title("mean %.3f (+- %.3f), min = %.3f, max = %.3f" %
(np.mean(times), np.std(times), np.min(times), np.max(times)))
plt.savefig("log2.png")
Result
I think I should better ask: How can I reduce this latency and tell my OS, that this thread is really important to me and should have a higher priority?
You are not measuring what you think you are measuring here:
start= std::chrono::system_clock::now();
auto Thread = std::thread([](){std::cout<<"Excuting thread"<<std::endl;});
stop = std::chrono::system_clock::now();
The stop timestamp only gives you an upper bound on how long it takes main to spawn that thread and it actually tells you nothing about when that thread will start doing any actual work (for that you would need to take a timestamp inside the thread).
Also, system_clock is not the best clock for such measurements on most platforms, you should use steady_clock by default and resort to high_resolution_clock if that one doesn't give you enough precision (but note that you will have to deal with the non-monotonic nature of that clock by yourself then, which can easily mess up the gained precision for you).
As was mentioned already in the comments, spawning a new thread (and thus also constructing a new std::thread) is a very complex and time-consuming operation. If you need high responsiveness, what you want to do is spawn a couple of threads during startup of your program and then have them wait on a std::condition_variable that will get signalled as soon as work for them becomes available. That way you can be sure that on an otherwise idle system a thread will start processing the work that was assigned to him very quickly (immediately is not possible on most systems due to how the operating system schedules threads, but the delay should be well under a millisecond).

wait_until behavior for time_point::max

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.

boost thread and try_join_for gives different output each time

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.