尝试获取QSemaphore时互斥锁解锁失败

时间:2017-01-04 09:44:17

标签: multithreading qt synchronization qthread

我有一个带有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 个答案:

答案 0 :(得分:0)

可能你在其他地方做错了(例如,信号量初始化代码)。

以下示例编译并运行(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