尝试获取 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);

ma​​in.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

【讨论】:

提示:您的示例不需要使用&lt;iostream&gt;,也不需要使用多个文件。使用qDebug() &lt;&lt; "Success"; 并在main.cpp 中仅使用一个#include &lt;QtCore&gt; @Kuba Ober threads.h 因为 moc 而存在,threads.cpp 用于在单独的翻译单元中本地化信号量。而且我更喜欢语言的标准库而不是 Qt 的实现(口味问题):-) 我已经删除了信号量并用 QWaitCondition 和 QMutex 替换了每个信号量,现在它工作得很好。我没有做任何其他更改,我仍然不知道为什么带有信号量的版本不正确。它们都被初始化为 0。 这两个QThread 派生类不需要Q_OBJECT 宏。但如果他们这样做了,您只需在 main.cpp 末尾添加 #include "main.moc" 对,不是在这种情况下,修复它。谢谢@KubaOber

以上是关于尝试获取 QSemaphore 时互斥锁解锁失败的主要内容,如果未能解决你的问题,请参考以下文章

qt QSemaphore

mysql innodb 行锁解锁后出现死锁

linuxbingc(多线程)

linuxbingc(多线程)

linuxbingc(多线程)

Record is locked by another user --Oracle行锁解锁