I have a thread which modifies one atomic variable (bool) and another thread which wants to poll that variable. My application makes few function calls in thread A
and start polling on one specific atomic variable. Thread B
keeps on reading the status of some external application (application on dbus
) and modifies few atomic variable accordingly. A function in Thread A
wants to make sure that if it returns, then some external application has changed it's state to desired state which it will get to know via these atomic flags.
Details of my application:
The function in thread A
is start_scan()
function which starts scanning nearby BLE devices using dbus API
. However, even if start scan
call was successful but external application (org.bluez
) still takes some time to update it's properties (Property: Discovering
). I have also defined functions like isScanning
which queries some variables (internal to my application) for current status of external application. Whenever, external application's properties are updated, it notifies other application via PropertiesChanged
signal over dbus
and yes, it takes some time (less than a second) before i receive PropertiesChanged
signal for scanning after successful call to start_scan
. So, I am thinking to poll for my local atomic flags (with my own timeout mechanism) before i return from start_scan
function, This will make sure if someone queries status of scanning after calling start_scan
, then isScanning
will return a valid state.
I can't use condition_variable as I have many functions and flags which needs to be in syn.
Problem:
std::atomic<bool> scanning_;
// Thread A
void start_scan()
{
// Dbus methods call
while (scanning_ == false) { // With some timeout
// Timeout mechanism
}
}
// Thread B receving asyn signals from DBus
void propertyUpdate(std::string name, bool value)
{
if (name == "Discovering")
scanning_ = value;
...
}
When thread A will be polling for scanning_
flag, thread B will receive dbus
signal to update scanning_
flag. I am not sure if Thread A
will choke thread B as if it will be continuously reading the flag and my flag is atomic? I want to know how thread waiting for atomic variables access are scheduled if atomic variable becomes available?
EDIT:
I am doing something like this:
void setter(bool value)
{
std::lock_guard<std::mutex lock(mutex_);
member_ = value;
}
bool getter(void)
{
std::lock_guard<std::mutex lock(mutex_);
return member_;
}
// Thread A is blocking on a class member value
while (getter() == false);
// Thread B will modify the class member when required
setter(true);
I want to know the possible problem I can face because of scheduling of blocked threads on a common mutex. Is it possible that thread A will keep on acquiring mutex_ while thread B will be blocked forever. It could occur if thread B is not scheduled after getter
function in thread A returns and before thread A acquires mutex_ again.
If you need to block a thread until a condition becomes true (in your case, scanning_
with a timeout), then you should use condition variables. This way, scanning_
would be just a normal variable, not an atomic one, and it will be protected by a mutex.
(Using atomic variables for some thread communication is possible, but you cannot make a thread sleep with just using atomic variables. In your example, start_scan constantly runs, eats CPU time)