【发布时间】:2017-06-28 01:09:14
【问题描述】:
我有一个线程修改一个原子变量 (bool) 和另一个线程想要轮询该变量。我的应用程序在thread A 中进行了很少的函数调用,并开始轮询一个特定的原子变量。 Thread B 不断读取一些外部应用程序 (application on dbus) 的状态并相应地修改一些原子变量。 Thread A 中的一个函数想要确保如果它返回,那么某些外部应用程序已将其状态更改为所需的状态,它将通过这些原子标志了解。
我的申请详情:
thread A 中的函数是start_scan() 函数,它使用dbus API 开始扫描附近的 BLE 设备。然而,即使start scan 调用成功但外部应用程序 (org.bluez) 仍然需要一些时间来更新它的属性 (Property: Discovering)。我还定义了像isScanning 这样的函数,它查询一些变量(在我的应用程序内部)以获取外部应用程序的当前状态。每当更新外部应用程序的属性时,它会通过dbus 上的PropertiesChanged 信号通知其他应用程序,是的,在成功调用start_scan 后,我需要一些时间(不到一秒)才能收到PropertiesChanged 信号进行扫描.所以,我想在我从start_scan 函数返回之前轮询我的本地原子标志(使用我自己的超时机制),这将确保如果有人在调用start_scan 后查询扫描状态,那么isScanning 将返回一个有效的状态。
我不能使用 condition_variable,因为我有很多需要同步的函数和标志。
问题:
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;
...
}
当线程 A 将轮询 scanning_ 标志时,线程 B 将收到 dbus 信号以更新 scanning_ 标志。我不确定Thread A 是否会阻塞线程 B,就好像它会不断读取标志并且我的标志是原子的?我想知道如果原子变量可用,等待原子变量访问的线程是如何安排的?
编辑:
我正在做这样的事情:
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 将被永远阻塞。如果在线程 A 中的 getter 函数返回之后和线程 A 再次获取 mutex_ 之前未调度线程 B,则可能会发生这种情况。
【问题讨论】:
-
你不能使用互斥体或信号量吗?
-
轮询是对资源的浪费,标准不保证它永远有效。使用条件变量。
-
@n.m.: 你的意思是说如果我的线程轮询一个被其他线程修改的变量,我的线程不会看到更新吗?
-
你能详细说明吗?
-
如果一个线程正在轮询,则不能保证任何其他线程都有机会运行..
标签: c++ multithreading stdatomic