Waiting Thread Until a Condition Has Been Occurred

waiting thread until a condition has been occurred

You need conditional variables.

If your compiler supports std::conditional introduced by C++11, then you can see this for detail:

  • std::condition_variable (C++11 threads)

If your compiler doesn't support it, and you work with win32 threads, then see this:

  • Condition Variables (Win32 threads)

And here is a complete example.

And if you work with POSIX threads, then see this:

  • Condition Variables (POSIX threads)

You can see my implementation of conditional_variable using win32 primitives here:

  • Implementation of concurrent blocking queue for producer-consumer

Scroll down and see it's implementation first, then see the usage in the concurrent queue implementation.

A typical usage of conditional variable is this:

//lock the mutex first!
scoped_lock myLock(myMutex);

//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);

//Execute this code only if the condition is met

whereCheckCondition is a function (or functor) which checks the condition. It is called by wait() function internally when it spuriously wakes up and if the condition has not met yet, the wait() function sleeps again. Before going to sleep, wait() releases the mutex, atomically.

waiting thread until a condition has been occurred

You need conditional variables.

If your compiler supports std::conditional introduced by C++11, then you can see this for detail:

  • std::condition_variable (C++11 threads)

If your compiler doesn't support it, and you work with win32 threads, then see this:

  • Condition Variables (Win32 threads)

And here is a complete example.

And if you work with POSIX threads, then see this:

  • Condition Variables (POSIX threads)

You can see my implementation of conditional_variable using win32 primitives here:

  • Implementation of concurrent blocking queue for producer-consumer

Scroll down and see it's implementation first, then see the usage in the concurrent queue implementation.

A typical usage of conditional variable is this:

//lock the mutex first!
scoped_lock myLock(myMutex);

//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);

//Execute this code only if the condition is met

whereCheckCondition is a function (or functor) which checks the condition. It is called by wait() function internally when it spuriously wakes up and if the condition has not met yet, the wait() function sleeps again. Before going to sleep, wait() releases the mutex, atomically.

Wait main thread until condition

The other two answers are correct when you are running a multithreading application, but this is a Single thread application.

ROS use ros::spinOnce() to:

Process a single round of callbacks.

This method is useful if you have your own loop running and would like
to process any callbacks that are available. This is equivalent to
calling callAvailable() on the global CallbackQueue. It will not
process any callbacks that have been assigned to custom queues.

Thanks to Jonathan Wakely to point me to the right direction. Sorry, I'm learning and I didn't know that.

I finally fixed using this code:

//*********************************************
// I want to wait here.
//*********************************************

while (ros::ok)
{
ros::spinOnce();
loop_rate.sleep();

if (!is_init_pos)
break;
}

is there a 'block until condition becomes true' function in java?

Polling like this is definitely the least preferred solution.

I assume that you have another thread that will do something to make the condition true. There are several ways to synchronize threads. The easiest one in your case would be a notification via an Object:

Main thread:

synchronized(syncObject) {
try {
// Calling wait() will block this thread until another thread
// calls notify() on the object.
syncObject.wait();
} catch (InterruptedException e) {
// Happens if someone interrupts your thread.
}
}

Other thread:

// Do something
// If the condition is true, do the following:
synchronized(syncObject) {
syncObject.notify();
}

syncObject itself can be a simple Object.

There are many other ways of inter-thread communication, but which one to use depends on what precisely you're doing.

How to block until a condition is met

Assuming that there's another thread that's actually going to do something here, an easy thing to use is a std::condition_variable:

std::condition_variable cv;
std::mutex mtx;

void WaitForProjectsCompleted() {
std::unique_lock<std::mutex> lk(mtx);
cv.wait(lk, [this]{
return projects_completed >= 12;
});
}

Where somewhere else, some other member function might do:

void CompleteProject() {
{
std::lock_guard<std::mutex> lk(mtx);
++projects_completed;
}
cv.notify_one(); // let the waiter know
}

If projects_completed is atomic, you could instead just spin:

void WaitForProjectsCompleted() {
while (projects_completed < 12) ;
}

That would work fine too.

Wait in threads for some time, OR until condition occurs

I am not sure how you tested it for multiple threads, but you got wrong results. Condition variable wait() or wait_for() call unlocks mutex when it waits for the signal. Otherwhise why would you have to pass lock to that function?

Notice that the lock is passed to wait: wait will atomically add the thread to the set of threads waiting on the condition variable, and unlock the mutex. When the thread is woken, the mutex will be locked again before the call to wait returns. This allows other threads to acquire the mutex in order to update the shared data, and ensures that the data associated with the condition is correctly synchronized.

How to wait for thread to retire in C++?

Answer: Predicate parameter in C++11 condition variable. https://en.cppreference.com/w/cpp/thread/condition_variable/wait

Using std::conditional_variable to wait on a condition

Condition variables wake things up spuriously.

You must have a mutex and it must guard a message of some kind for them to work, or you have zero guarantee that any such wakeup occurred.

This was done, presumably, because efficient implementations of a non-spurious version end up being implemeneted in terms of such a spurious version anyhow.

If you fail to guard the message editing with a mutex (ie, no synchronization on it, the state of the message is undefined behavior. This can cause compilers to optimize the read from memory to skip it after the first read.

Even excluding that undefined behavior (imagine you use atomics), there are race conditions where a message is set, a notification occurs, and nobody waiting on the notification sees the message being set if you fail to have the mutex acquired in the time between the variable being set and the condition variable being notified.

Barring extreme cases, you usually want to use the lambda version of wait.

Auditing condition variable code is not possible unless you audit both the notification code and the wait code.

struct gate {
bool gate_open = false;
mutable std::condition_variable cv;
mutable std::mutex m;

void open_gate() {
std::unique_lock<std::mutex> lock(m);
gate_open=true;
cv.notify_all();
}
void wait_at_gate() const {
std::unique_lock<std::mutex> lock(m);
cv.wait( lock, [this]{ return gate_open; } );
}
};

or

  void open_gate() {
{
std::unique_lock<std::mutex> lock(m);
gate_open=true;
}
cv.notify_all();
}

After signaling a waiting condition variable, when the thread will acquire the lock? What determines it?

The behavior of a condition variable is that of releasing the lock and waiting (atomically) and then re-acquiring the lock when the thread is signaled. In your code, one thread is signaling the other while holding the mutex, and the implication is that the woken up thread is going to enter the wait queue in the mutex until the other thread releases the mutex.



Related Topics



Leave a reply



Submit