C++ 在互斥锁锁定的情况下,如何处理主线程中的信号?

C++ 在互斥锁锁定的情况下,如何处理主线程中的信号?,c++,multithreading,qt,c++11,mutex,C++,Multithreading,Qt,C++11,Mutex,我正在编写一个多线程Qt应用程序,但由于OpenGL相关调用,部分代码必须始终在主线程中执行 模拟问题的粗略代码如下: QMutex mutex; void openGLCalls() { } void foo1() { mutex.lock(); openGLCalls(); mutex.unlock(); } class CBHandler : public QObject { public: CBHandler(QObject *parent = N

我正在编写一个多线程Qt应用程序,但由于OpenGL相关调用,部分代码必须始终在主线程中执行

模拟问题的粗略代码如下:

QMutex mutex;

void openGLCalls()
{
}
void foo1()
{
    mutex.lock();
    openGLCalls();
    mutex.unlock();

}

class CBHandler : public QObject
{

public:
    CBHandler(QObject *parent = NULL)
    {
        connect(this, SIGNAL(requestCallbackExec()), SLOT(runCallback()),    Qt::BlockingQueuedConnection);

    }

    static CBHandler *Instance();

    public slots:

    void runCallback  ()
    {
        //in the main thread as object lies there
        openGLCalls();
    }

signals:
    void requestCallbackExec ();

};

class Thread1
{
    void run()
    {
        while(1)
        {
            mutex.lock();
            CBHandler::Instance()->emit requestCallbackExec();
            mutex.unlock();
        }
    }
};

void main()
{

    Thread1 thread;
    CBHandler cbhandler;
    thread.start();
    while(1)
    {
        if(/*some key pressed*/)
        {
            foo1();
        }
    }
}
上面的代码确保“openGLCalls()”始终在主线程中执行。 但问题是,如果互斥锁被Thread1锁定,并且主线程尝试调用foo1,那么当主线程尝试锁定互斥锁时,它就会休眠。
由于主线程处于睡眠状态,Thread1锁定的互斥锁永远不会解锁,因为“requestCallbackExec”信号从未得到处理。

您应该让事件循环在
.lock()
等待时旋转。似乎没有办法做到这一点。因此,您可以等待:

while(!mutex.tryLock()) {
    QEventLoop loop;
    loop.processEvents();
}

您可以在
.tryLock()
调用中添加一个超时来不加热CPU,但这会花费一些延迟。

您的互斥锁到底保护什么?“//做点什么”。互斥确保//do something由主线程或工作线程执行。我将//do something替换为“openGLCalls()”,但它不是一个函数。主线程可能会做一些可以更改数据的事情,而工作线程可能希望通过其他代码读取这些数据。这不会计算。工作线程(1)请求启动回调(2)读取共享数据。第二件事需要一个互斥锁来保护。但是你为什么要保护第一个呢?你的
foo1()
可以
tryLock()
互斥锁并在失败时返回这解决了问题,但是因为我是stackoverflow新手,所以我的投票不算。但是我自己找到了一个更好的解决方案。如果其他人感兴趣,我将QWaitCondition与QCoreApplication::postEvent()一起使用。当然,接收器和事件必须由您自己定义,以便您可以调用'QWaitCondition::wakeOne()