简体   繁体   中英

How do I process signals in main thread with mutex locked?

I am writing a multi-threaded Qt Application but because of OpenGL related calls, some part of the code has to be always executed in the main thread.

Rough code to simulate the problem will be:

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();
        }
    }
}

Above code ensures that "openGLCalls()" is always executed in the main thread. But problem is, if the mutex is locked by Thread1 and the main thread tries to call foo1 then main thread sleeps when trying to lock the mutex. And since main thread is sleeping, mutex locked by Thread1 never gets unlocked because of 'requestCallbackExec' signal never getting processed.

You should let the event loop spin while .lock() is waiting. There seems to be no method to do it. So you could busy wait:

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

You could add a timeout to the .tryLock() call to not heat CPU but it would cost you some latency.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM