【发布时间】:2011-06-17 21:06:00
【问题描述】:
我正在开发一个多线程 QT 项目。主要问题出在串行控制器类上。该类使用 QMutex 和 QWaitCondition 来同步写入和读取方法。
问题是由于父级中的 qwaitcondition 等待方法导致子级中的信号阻塞。一旦wait方法返回,就会发出子类中的信号(接收者也是子类)。
我认为这种方法(qwaitcondition - wait)会阻止我整个应用程序中的任何信号发射。
问题是这样的:
constructor()
{
anotherclass = new MyClass;
}
void run()
{
forever
{
if(readmethod())
waitcondition.wakeall();
}
}
void method1()
{
sendpacket();
mutex.lock();
if(waitcondition.wait(&mutex,10000))
//somecode;
mutex.unlock();
}
class MyClass
{
someObject sobj;
MyClass()
{
connect(sobj,SIGNAL(somesignal),this,SLOT(someslot));
}
void someslot()
{
//some code
}
}
只有当 qwaitcondition 由于超时(本例中为 10 秒)返回时,才会调用我的名为 someslot 的插槽。
我只想在这个类中使用互斥锁和 qwaitcondition,而不是在整个应用程序中。我试图在主线程中实例化子类,但我得到了相同的行为。
概念测试
我做了一个测试项目,并在这个链接上发布了它: testwaitconditionproject
测试项目以这种方式工作: 等待条件在父线程中的超时等于 10 秒时启动。 子线程每 2 秒发出一个信号,内部插槽必须发出由父线程捕获的信号。一旦调用父插槽,就会将标志设置为 true。此标志应触发唤醒以完成 de waitcondition。
但不是,只有在等待条件超时后才会触发子级的内部信号。这是我的主要问题,父母等待条件阻止了我孩子的信号。
编辑:
我在测试项目中解决了这个问题,在另一个线程中调用了带有等待条件的方法。我无法复制该问题,因为对该方法的异步调用发生在线程 1 中(通过 dbus)。我想知道 dbus 调用是在线程 1 中发出的,所以当实例属于同一个线程时,我在子类中的事件不会被发出。
编辑 2:
我解决了将父级和子级放在中间类 qthread 中的问题。它们在 run 方法中被实例化,并且也使用了 exec 调用。
【问题讨论】:
-
你是如何创建新线程的?您确定等待是在新线程中而不是主线程中吗?我发现通过设置 UI 线程和新线程的 objectName 来检查这一点,然后在各种调用中检查 thread()->objectName() 有助于验证这样的事情。
-
我正在使用waitcondition来同步同一个线程中的两个方法,run方法和另一个异步调用的方法。子线程在其父线程的构造函数中实例化,但我试图从主线程实例化它而没有任何结果。我尝试使用 objectName 来验证它,而孩子们是另一个线程。你知道它为什么会这样吗?
-
run 方法应该在新构建的线程中运行。然后需要从不同的线程(可能是 UI 线程)调用 method1。这将导致调用 method1 的线程等待直到 run 方法将其唤醒。如果从同一个线程调用等待条件和等待,它将不起作用。你能发布一个工作样本吗?
-
Brett,我在帖子中添加了测试项目。
标签: qt mutex signals signals-slots slot