C++ 在互斥锁锁定的情况下,如何处理主线程中的信号?
我正在编写一个多线程Qt应用程序,但由于OpenGL相关调用,部分代码必须始终在主线程中执行 模拟问题的粗略代码如下: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
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()