在Qt中,我有一个包含互斥锁和解锁的方法。问题是当互斥锁解锁时,有时需要很长时间才能使另一个线程获得锁定。换句话说,即使另一个线程正在等待它,似乎同一个线程可以获得锁定(在循环中调用的方法)。我该怎么办?一个线程是qthread,另一个线程是主线程。
答案 0 :(得分:4)
您可以让刚刚解锁互斥锁的线程放弃处理器。在Posix上,您可以通过致电pthread_yield()
来调用Sleep(0)
。
也就是说,无法保证等待锁定的线程会在线程再次唤醒之前进行调度。
答案 1 :(得分:0)
如果某个其他线程已在等待它,则不应该释放锁定然后将其取回。
如果您认为自己确实释放了锁定,请检查。检查等待线程是否实际等待(并且没有使用trylock测试旋转循环并且睡眠,我实际上已经完成了一次并且在开始时非常困惑:))。
或者,如果等待线程真的永远无法获得锁定代码,请尝试QThread :: yieldCurrentThread()。这将停止当前线程并为调度程序提供执行给其他人的机会。可能会导致不必要的切换,具体取决于循环的紧密程度。
答案 2 :(得分:0)
如果要确保一个线程优先于其他线程,则选项是使用QReadWriteLock
。它适用于n个线程将在无限循环中读取值的典型场景,只有一个线程更新它。我认为这是你所描述的情景。
QReadWriteLock
提供两种锁定方式:lockForRead()
和lockForWrite()
。取决于值的线程将使用后者,而更新值的线程(通常通过GUI)将使用前者(lockForWrite()
)并具有最高优先级。你不需要睡觉或屈服或其他什么。
假设您某处有QReadWrite lock;
。
“读者”主题
forever {
lock.lockForRead();
if (condition) {
do_stuff();
}
lock.unlock();
}
“作家”主题
// external input (eg. user) changes the thread
lock.lockForWrite(); // will block as soon as the reader lock ends
update_condition();
lock.unlock();