尝试获取 QSemaphore 时互斥锁解锁失败
Posted
技术标签:
【中文标题】尝试获取 QSemaphore 时互斥锁解锁失败【英文标题】:Mutex unlock failure when trying to acquire a QSemaphore 【发布时间】:2017-01-04 09:44:17 【问题描述】:我有一个带有 2 个 QThreads 的应用程序,它们的行为类似于下面的伪代码(信号量是 QSemaphore 类型):
Thread1
print("about to wait on semaphore 1");
sem1.acquire(1);
print("finished waiting on semaphore 1");
sem2.release(1);
Thread2
print("signaling semaphore 1");
sem1.release(1);
print("about to wait on semaphore 2");
sem2.acquire(1);
问题是当第一个信号量发出信号时第一个线程没有唤醒,即应用程序产生以下输出:
about to wait on semaphore 1
signaling semaphore 1
about to wait on semaphore 2
就是这样。第一个线程不再唤醒。
现在我更改第一个线程以执行以下操作:
Thread1
print("about to wait on semaphore 1");
while (!sem1.tryAcquire(1, 200));
print("finished waiting on semaphore 1");
sem2.release(1);
在这种情况下,第一个线程在尝试再次获取信号量之前最多休眠 200 毫秒。现在我收到以下错误:
QWaitCondition::wait(): mutex unlock failure: Invalid argument
应用程序不使用其他互斥锁或其他同步原语。可能是什么问题?
更新:
我删除了信号量并将每个信号量替换为 QWaitCondition 和 QMutex,现在它工作得很好。我没有做任何其他更改,我仍然不知道为什么带有信号量的版本不正确。它们都被初始化为0。
【问题讨论】:
【参考方案1】:您可能在其他地方做错了什么(例如,信号量初始化代码)。
以下示例编译并运行 (gcc)。
threads.h:
#pragma once
#include <QThread>
class Thread1 : public QThread
protected:
virtual void run();
;
class Thread2 : public QThread
protected:
virtual void run();
;
threads.cpp:
#include "threads.h"
#include <QSemaphore>
#include <iostream>
namespace
QSemaphore sem1, sem2;
void Thread1::run()
std::cout << "about to wait on semaphore 1\n";
sem1.acquire(1);
//while (!sem1.tryAcquire(1, 200)); //works too
std::cout << "finished waiting on semaphore 1\n";
sem2.release(1);
void Thread2::run()
std::cout << "signaling semaphore 1\n";
sem1.release(1);
std::cout << "about to wait on semaphore 2\n";
sem2.acquire(1);
main.cpp:
#include "threads.h"
#include <iostream>
int main(int argc, char *argv[])
Thread1 t1;
Thread2 t2;
t1.start();
t2.start();
t1.wait();
t2.wait();
std::cout << "Success\n";
可能的输出:
signaling semaphore 1
about to wait on semaphore 2
about to wait on semaphore 1
finished waiting on semaphore 1
Success
【讨论】:
提示:您的示例不需要使用<iostream>
,也不需要使用多个文件。使用qDebug() << "Success";
并在main.cpp
中仅使用一个#include <QtCore>
。
@Kuba Ober threads.h 因为 moc 而存在,threads.cpp 用于在单独的翻译单元中本地化信号量。而且我更喜欢语言的标准库而不是 Qt 的实现(口味问题):-)
我已经删除了信号量并用 QWaitCondition 和 QMutex 替换了每个信号量,现在它工作得很好。我没有做任何其他更改,我仍然不知道为什么带有信号量的版本不正确。它们都被初始化为 0。
这两个QThread
派生类不需要Q_OBJECT
宏。但如果他们这样做了,您只需在 main.cpp
末尾添加 #include "main.moc"
。
对,不是在这种情况下,修复它。谢谢@KubaOber以上是关于尝试获取 QSemaphore 时互斥锁解锁失败的主要内容,如果未能解决你的问题,请参考以下文章