Я пишу многопоточное приложение 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 () всегда выполняется в основном потоке.Но проблема в том, что если мьютекс заблокирован потоком 1 и основной поток пытается вызвать foo1, то основной поток спит при попытке заблокировать мьютекс.А поскольку основной поток находится в спящем режиме, мьютекс, заблокированный Thread1, никогда не разблокируется из-за того, что сигнал 'requestCallbackExec' никогда не обрабатывается.