用C ++查询原子变量(bool)?

时间:2017-06-28 01:09:14

标签: c++ multithreading stdatomic

我有一个修改一个原子变量(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,则可能发生这种情况。

1 个答案:

答案 0 :(得分:3)

如果您需要阻止线程直到条件变为真(在您的情况下,scanning_超时),那么您应该使用condition variables。这样,scanning_只是一个普通变量,而不是原子变量,它将受到互斥锁的保护。

(使用原子变量进行某些线程通信是可能的,但是你不能只使用原子变量使线程休眠。在你的例子中,start_scan不断运行,占用CPU时间)