我有一个修改一个原子变量(bool)的线程和另一个想要轮询该变量的线程。我的应用程序在thread A
中进行少量函数调用,并开始轮询一个特定的原子变量。 Thread B
继续读取某些外部应用程序(application on dbus
)的状态,并相应地修改几个原子变量。 Thread A
中的函数想要确保如果它返回,那么一些外部应用程序已将其状态更改为所需状态,它将通过这些原子标记获知。
我的申请详情:
thread A
中的功能是start_scan()
功能,它使用dbus API
开始扫描附近的BLE设备。但是,即使start scan
调用成功,但外部应用程序(org.bluez
)仍需要一些时间来更新其属性(Property: Discovering
)。我还定义了像isScanning
这样的函数,它们查询一些变量(我的应用程序内部)以获取外部应用程序的当前状态。每当外部应用程序的属性更新时,它会通过PropertiesChanged
上的dbus
信号通知其他应用程序,是的,在我收到PropertiesChanged
信号进行扫描之前需要一些时间(不到一秒)成功拨打start_scan
。因此,我想在从start_scan
函数返回之前轮询我的本地原子标志(使用我自己的超时机制),这将确保在调用start_scan
之后有人查询扫描状态,然后{ {1}}将返回有效状态。
我不能使用condition_variable,因为我有许多需要在syn中的函数和标志。
问题:
isScanning
当线程A将轮询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;
...
}
标志时,线程B将收到scanning_
信号以更新dbus
标志。我不确定scanning_
是否会阻塞线程B,好像它将继续读取标志并且我的标志是原子的?我想知道如果原子变量可用,如何调度等待原子变量访问的线程?
修改
我正在做这样的事情:
Thread A
我想知道由于在常见互斥锁上安排阻塞线程而可能遇到的问题。是否有可能线程A将继续获取mutex_,而线程B将永远被阻塞。如果在线程A中的 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);
函数返回之后并且线程A再次获取mutex_之前未调度线程B,则可能发生这种情况。
答案 0 :(得分:3)
如果您需要阻止线程直到条件变为真(在您的情况下,scanning_
超时),那么您应该使用condition variables。这样,scanning_
只是一个普通变量,而不是原子变量,它将受到互斥锁的保护。
(使用原子变量进行某些线程通信是可能的,但是你不能只使用原子变量使线程休眠。在你的例子中,start_scan不断运行,占用CPU时间)