[英]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.