【发布时间】:2019-04-05 06:31:35
【问题描述】:
我正在编写一个多线程的 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()”始终在主线程中执行。 但问题是,如果互斥锁被 Thread1 锁定并且主线程尝试调用 foo1,那么主线程在尝试锁定互斥锁时会休眠。 由于主线程处于休眠状态,因此被 Thread1 锁定的互斥体永远不会被解锁,因为“requestCallbackExec”信号永远不会得到处理。
【问题讨论】:
-
你的互斥锁到底保护的是什么?
-
'//做点什么'。 mutex 确保 //do 某事由主线程或工作线程执行
-
我用'openGLCalls()'替换了//do something,但它不完全是一个函数。主线程可能会做一些可以改变数据的事情,而工作线程可能想通过其他代码来读取。
-
这不计算。工作线程 (1) 请求启动回调并 (2) 读取共享数据。第二件事需要由互斥锁保护。但是你为什么要保护第一个呢?
-
你的
foo1()可以tryLock()互斥体并在失败时返回
标签: c++ multithreading qt c++11 mutex