我使用 QtConconcurrent 在后台线程中执行发现过程:
// Start the discover process in the background thread so it doesn't block the gui
*m_Future = QtConcurrent::run(this, &Controller::StartDiscover);
m_Watcher->setFuture(*m_Future);
我以前没有放置一个互斥体来保护该函数中的共享变量,这些变量可以在后台线程运行时访问。这在我的"扫描"操作期间导致一些随机锁定。
我现在已经实现了互斥锁,在该函数的开头创建了一个 QMutexLocker。
int Controller::StartDiscover() {
// Lock mutex
QMutexLocker ml(&m_Mutex);
// Zero
m_NumberBoundDevices = 0;
// Update to scanning
m_Status = Scanning;
// Discover slaves
int numberAttachedSlaves = m_Client->DiscoverSlaves();
m_Client->setTimeout(20000); // 20 Second Timeout
if ( numberAttachedSlaves > 0 ) {
int cnt = 0;
while ( cnt < 3 ) {
for (int slave = 1 ; slave <= numberAttachedSlaves ; slave++ ) {
// Get information about this slave
QDBusPendingReply<uchar> reply = m_Client->SlaveService(slave,m_Packet);
reply.waitForFinished(); // Wait for it to complete
if (!reply.isValid()) {
m_Client->SlaveService(slave,m_Packet);
reply.waitForFinished();
}
if ( reply.isError() ) {
QString errorMsg = reply.reply().errorMessage();
}
}
// Increment counter
cnt++;
}
}
// Update
m_NumberBoundDevices = numberAttachedSlaves;
// Return the number of devices discovered
return numberAttachedSlaves;
}
这会保护函数中的所有共享变量吗?或者,我应该在每个m_*变量周围显式使用QMutex.lock()和unlock()吗?
谢谢
考虑一下: -
char buffer[]
void ReadFromBuffer()
{
QMutexLocker ml(&m_Mutex);
// read contents of buffer
}
void WriteToBuffer()
{
QMutexLocker ml(&m_Mutex);
// write to buffer
}
如果 ReadFromBuffer 在与 WriteToBuffer 不同的线程中运行,则希望确保读取和写入不会同时发生。
如果一个线程在 WriteToBuffer 中执行并锁定互斥锁,则当另一个线程进入 ReadFromBuffer 并执行其互斥锁锁时,它会检查互斥锁是否已锁定。如果它被锁定,线程将暂停并等待它被解锁。当 QMutexLocker 对象超出锁定互斥锁的第一个函数的范围时,会发生这种情况。
这就是为什么所有访问共享对象的代码都需要QMutexLocker的原因。