简体   繁体   English

如何处理锁定互斥锁的主线程中的信号?

[英]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.我正在编写一个多线程 Qt 应用程序,但由于与 OpenGL 相关的调用,代码的某些部分必须始终在主线程中执行。

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.上面的代码确保“openGLCalls()”总是在主线程中执行。 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.但问题是,如果互斥锁被 Thread1 锁定并且主线程尝试调用 foo1,那么主线程在尝试锁定互斥锁时会休眠。 And since main thread is sleeping, mutex locked by Thread1 never gets unlocked because of 'requestCallbackExec' signal never getting processed.并且由于主线程正在休眠,被 Thread1 锁定的互斥锁永远不会被解锁,因为 'requestCallbackExec' 信号永远不会被处理。

You should let the event loop spin while .lock() is waiting.您应该在.lock()等待时让事件循环旋转。 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.您可以向.tryLock()调用添加超时以不加热 CPU,但这会花费您一些延迟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在QT中使用互斥锁锁定线程开始轮询? - How do I start polling with mutex locked thread in QT? 是否需要使用互斥锁锁定thread_local变量? - Do thread_local variables need to be locked using a mutex? 如何避免由睡眠线程锁定(拥有)的互斥锁上的许多线程锁定? - How can I avoid lock of many threads on mutex which locked (owned) by thread which sleep? 我是否必须阻止主线程上的信号才能处理另一个线程上的取消点? - Do I have to block signals on the main thread to handle cancel point on another thread? 解锁另一个线程锁定的互斥锁 - Unlocking a mutex locked by another thread 如何避免互斥变量被同一线程两次锁定? - How to avoid a mutex variable being locked twice by the same thread? 如何在单独的线程中处理套接字请求,线程似乎阻塞了主进程 - How do I handle socket requests in separate threads, thread seems to be blocking main process 增强共享互斥锁检查是否锁定在同一线程中 - boost shared mutex check if locked in the same thread 在已经锁定的pthread_mutex_t上执行pthread_mutex_init时会发生什么? - What happens when I do a pthread_mutex_init on an already locked pthread_mutex_t? 取消已锁定互斥锁的线程不会解锁互斥锁 - Cancelling a thread that has a mutex locked does not unlock the mutex
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM