boost::condition_variable.timed_wait return immediately - c++

I'm working on a little threading library and have run into a problem. boost::condition_variable.wait() works perfectly, however boost::condition_variable.timed_wait() returns immediately, it doesn't time out.
The documentation says it should only return once the timeout has passed or it's been notified. It's a three second wait before notification and I've tried both 10 second and 100 second timouts, so it should return after 3 seconds.
EDIT:
boost::condition_variable waitCondition;
boost::mutex mMutex;
Message MessageClient::waitAsync(Message msg, bool waitForReply) {
unique_lock<boost::mutex> lock(msg->mMutex);
if(mSendTimeout.sec == 0)
msg->waitCondition.wait(lock);
else {
timeout = msg->waitCondition.timed_wait(lock, mSendTimeout);
if(!timeout)
return 0;
if(waitForReply) {
Message reply = receiveMessage();
return reply;
}
else
return 0;
}
This is called after a sendMessage. The receiver get the message, sends the reply and then calls
waitCondition.notify_all();

Condition variable waits can occasionally result in spurious wakeups. As such, you must use them in a loop:
while (someCondition)
msg->waitCondition.wait(lock);
With timed_wait it's slightly more complex as you must recalculate your timeout to deal with however long it did, in fact, wait. Boost offers a variant with a predicate that, given an absolute timeout, will do the loop for you:
msg->waitCondition.timed_wait(lock, absoluteTimeout, boost::lambda::var(someFlag));
If you're still having problems, check that mSendTimeout is not negative or very small, and consider the use of an absolute timeout.

Related

Check for a condition periodically without blocking

In my project, function clipsUpdate reads some facts which are set by CLIPS without the interference of my C++ code. Based on the read facts, clipsUpdate calls the needed function.
void updateClips(void)
{
// read clipsAction
switch(clipsAction)
{
case ActMove:
goToPosition (0, 0, clipsActionArg);
break;
}
}
In goToPosition function, a message is sent to the vehicle to move to the specified position and then a while loop is used to wait until the vehicle reaches the position.
void goToPosition(float north, float east, float down)
{
// Prepare and send the message
do
{
// Read new location information.
}while(/*Specified position reached?*/)
}
The problem is that updateClips should be called every 500 ms and when the goToPosition function is called, the execution is blocked until the target location is reached. During this waiting period, something may happen that requires the vehicle to stop. Therefore, updateClips should be called every 500 ms no matter what, and it should be able to stop executing goToPosition if it's running.
I tried using threads as following, but it didn't work successfully with me and it was difficult for me to debug. I think it can be done with a simpler and cleaner way.
case ActMove:
std::thread t1(goToPosition, 0, 0, clipsActionArg);
t1.detach();
break;
My question is, how can I check if the target location is reached without blocking the execution, i.e., without using while?
You probably want an event-driven model.
In an event-driven model, your main engine is a tight loop that reads events, updates state, then waits for more events.
Some events are time based, others are input based.
The only code that is permitted to block your main thread is the main loop, where it blocks until a timer hits or a new event arrives.
It might very roughly look like this:
using namespace std::literals::chrono_literals;
void main_loop( engine_state* state ) {
bool bContinue = true;
while(bContinue) {
update_ui(state);
while(bContinue && process_message(state, 10ms)) {
bContinue = update_state(state);
}
bContinue = update_state(state);
}
}
update_ui provides feedback to the user, if required.
process_message(state, duration) looks for a message to process, or for 10ms to occur. If it sees a message (like goToPosition), it modifies state to reflect that message (for example, it might store the desired destionation). It does not block, nor does it take lots of time.
If no message is recived in duration time, it returns anyhow without modifying state (I'm assuming you want things to happen even if no new input/messages occur).
update_state takes the state and evolves it. state might have a last updated time stamp; update_state would then make the "physics" reflect the time since last one. Or do any other updates.
The point is that process_message doesn't do work on the state (it encodes desires), while update_state advances "reality".
It returns false if the main loop should exit.
update_state is called once for every process_message call.
updateClips being called every 500ms can be encoded as a repeated automatic event in the queue of messages process_message reads.
void process_message( engine_state* state, std::chrono::milliseconds ms ) {
auto start = std::chrono::high_resolution_clock::now();
while (start + ms > std::chrono::high_resolution_clock::now()) {
// engine_state::delayed is a priority_queue of timestamp/action
// ordered by timestamp:
while (!state->delayed.empty()) {
auto stamp = state->delayed.front().stamp;
if (stamp >= std::chrono::high_resolution_clock::now()) {
auto f = state->queue.front().action;
state->queue.pop();
f(stamp, state);
} else {
break;
}
}
//engine_state.queue is std::queue<std::function<void(engine_state*)>>
if (!state->queue.empty()) {
auto f = state->queue.front();
state->queue.pop();
f(state);
}
}
}
The repeated polling is implemented as a delayed action that, as its first operation, inserts a new delayed action due 500ms after this one. We pass in the time the action was due to run.
"Normal" events can be instead pushed into the normal action queue, which is a sequence of std::function<void(engine_state*)> and executed in order.
If there is nothing to do, the above function busy-waits for ms time and then returns. In some cases, we might want to go to sleep instead.
This is just a sketch of an event loop. There are many, many on the internet.

What is the issue with this conditional variable implementation?

I've implemented code to call a service API every 10 seconds using a c++ client. Most of the times I've noticed it is around 10 seconds but occassionally I see an issue like below where it look longer. I'm using conditional variable on wait_until. What's wrong with my implementation? Any ideas?
Here's the timing output:
currentDateTime()=2015-12-21.15:13:21
currentDateTime()=2015-12-21.15:13:57
And the code:
void client::runHeartbeat() {
std::unique_lock<std::mutex> locker(lock);
for (;;) {
// check the current time
auto now = std::chrono::system_clock::now();
/* Set a condition on the conditional variable to wake up the this thread.
This thread is woken up on 2 conditions:
1. After a timeout of now + interval when we want to send the next heartbeat
2. When the client is destroyed.
*/
shutdownHeartbeat.wait_until(locker, now + std::chrono::milliseconds(sleepMillis));
// After waking up we want to check if a sign-out has occurred.
if (m_heartbeatRunning) {
std::cout << "currentDateTime()=" << currentDateTime() << std::endl;
SendHeartbeat();
}
else {
break;
}
}
}
You might want to consider using the high_resolution_clock for your needs. system_clock is not guaranteed a high resolution, so that may be a part of the problem.
Note that it's definition is implementation dependent so you might just get a typedef back onto system_clock on some compilers.

Execute code every X seconds, but break immediately on event?

I am looking for a way to execute some code every X seconds but if an event occurs during the X seconds, break immediately.
Originally I had a while loop with a sleep statement at the end. However this was problematic because if the code was sleeping, I couldnt stop the code immediately and had to wait until the sleep had finished.
Is there any simple way I can execute then sleep, but interrupt this sleep on an event?
EDIT: Opted for a condition variable with notify_all().
You seem to have already found out an answer but conditional wait on mutex is the best solution here. You can essentially lock the mutex and throw it in a wait condition object along with some timeout. Some other thread can then signal/notify your thread using the same (shared) wait condition object. If nobody notifies/signals the mutex within specified timeout, the wait will simply come out of sleep.
The advantage of this interruptible sleep is that it's not a busy waiting.
I don't think you can interrupt sleep but you could have your code sleeping in shorter intervals and check for a signal regularly.
#include <thread>
#include <chrono>
int main()
{
using namespace std::chrono;
unsigned Y = 100;
unsigned X = 1;
bool signaled = false;
while (!signaled)
{
// Do Stuff every X seconds
high_resolution_clock::time_point const p = high_resolution_clock::now();
while (duration_cast<milliseconds>(high_resolution_clock::now() - p).count() <
duration_cast<milliseconds>(std::chrono::seconds(X)).count())
{
// Code to check for a signal every Y milliseconds
if (signaled)
{
break;
}
std::this_thread::sleep_for(milliseconds(Y));
}
}
return 0;
}
Note: System depedant clock resolutions; Possible trade-off with respect to CPU load when adjusting signal check frequency (depending on the demand of the signal check code);

how to send a flag each X minutes?

I am working in a kind of "control block" that has to send a flag each 6 minutes. The thing is that I don't know if there is a simple way of doing this. I have had though in use clock_t inside a loop till it reaches the 6 minutes, and then call a method that sends the flag and re-initialize the clock_t variable.
I forgot to explain something, sleep is not an option because the block works like a flow, it has to send something the whole time. Actually the flag will change what is sending
Thanks in advance
You can just sleep the thread for 6 minutes and then send the flag:
for(;;)
{
sendFlag();
sleep(6*60);
}
Here are some options for the sleep method, including C++11's std::this_thread::sleep_for.
You could simply use a thread function that switches a flag on or off and sleep it for 6 minutes at a time. For example:
bool flag = false;
int main() {
while(true) {
if (flag == true) {
flag = false;
}
}
return(0);
}
void threadFunc() {
flag = true;
sleep(360); //360 seconds is 6 minutes
}
NOTE: You will need to use a mutex or semaphore because the code written now is not thread safe. How you use threads is also operating system dependent. Unless you use C++11 of course.
You don't need a whole thread just for this. Use a system OS periodic timer callback.

Interruptible sleep in Qt?

I'm in a worker thread and want to sleep for a specified period of time (usually a few hundreds milliseconds), but the sleep should be interruptible. Here is what I have come up with
void DummyScope::sleepForSamples() {
if(m_sampleSleep < 100) {
MySleeper::sleep(m_sampleSleep);
return;
}
// sleep in periods of 100 ms, to be responsible for shutdown requests
qint64 t = QDateTime::currentMSecsSinceEpoch();
qint64 end = t + m_sampleSleep;
while(t + 100 <= end) {
MySleeper::sleep(100);
t = QDateTime::currentMSecsSinceEpoch();
// TODO: check here whether we are interrupted
}
if(end > t) {
MySleeper::sleep(end - t);
}
}
However that looks a bit convoluted and I wonder whether there's a better way to do this. Is using a QWaitCondition with a timeout-wait a better solution?
'Is using a QWaitCondition with a timeout-wait a better solution?'
Yes!
The sleep() loop, apart from needlessly running every 100ms, has an average 'interrupt' latency of 50ms.
Definitely wait on a condition variable and let the accompanying condition tell you why you were interrupted.
If you don't have to use QT-threads, c++11 and boost let you add a predicate to wait_for/timed_wait, so spurious wakeups don't mess with your timeout.
Of course, it is even more convienent if you can go 1 step further and don't bother with a timeout (if the condition variable can handle all cases).
You can wait directly on the mutex with QMutex::tryLock(int timeout), if you lock and unlock it from another thread.