Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
QWaitCondition导致的Qt事件处理问题_Qt_Mutex_Signals_Signals Slots_Slot - Fatal编程技术网

QWaitCondition导致的Qt事件处理问题

QWaitCondition导致的Qt事件处理问题,qt,mutex,signals,signals-slots,slot,Qt,Mutex,Signals,Signals Slots,Slot,我正在从事一个多线程QT项目。主要问题在于串行控制器类。此类使用QMutex和QWaitCondition来shyncronize写入和读取方法 问题是由于父类中的qwaitcondition wait方法导致子类中的信号被阻塞。wait方法返回后,子类中的信号将被接收(接收器也是子类) 我认为这个方法(qwaitcondition-wait)在我的整个应用程序中阻止了任何信号发射 问题是这样的: constructor() { anotherclass = new MyClass; }

我正在从事一个多线程QT项目。主要问题在于串行控制器类。此类使用QMutex和QWaitCondition来shyncronize写入和读取方法

问题是由于父类中的qwaitcondition wait方法导致子类中的信号被阻塞。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,而不是在整个应用程序中。我试图在主线程中实例化children类,但得到了相同的行为

概念测试

我制作了一个测试项目,并将其发布在以下链接:

测试项目的工作方式如下: 在父线程中,使用等于10秒的超时来初始化waitcondition。 子线程每2秒发出一个信号,内部插槽必须发出父线程捕获的信号。调用父插槽后,标志将设置为true。此标志应触发wakeall以完成取消等待条件

但并非如此,只有在waitcondition超时后才会触发子级的内部信号。这是我的主要问题,父母的等待状况阻碍了我孩子的信号

编辑:

我在测试项目中解决了这个问题,在另一个线程中使用waitcondition调用该方法。我不可能复制该问题,因为对该方法的异步调用发生在线程1中(通过dbus)。我想知道dbus调用是在线程1中发出的,因此当实例属于同一线程时,不会发出children类中的事件

编辑2:


我解决了将pparent和孩子们放在中间类qthread中的问题。它们在run方法中被实例化,并且还使用了exec调用。

您似乎没有运行QCoreApplication事件循环,这是处理事件所必需的。在QCoreApplication::exec()阻止事件循环之前调用的write()。此外,在具有事件循环的线程内创建所有QThread对象似乎很重要(如果您想使用来自此类对象的信号)。我举了您的例子,创建了运行pparent(并取消阻止QCoreApplication::exec())的附加线程,它运行得很好。

您如何创建新线程?您确定等待在新线程而不是主线程中吗?我发现通过设置UI线程和新线程的objectName来检查这一点,然后在各种调用中检查thread()->objectName(),可以帮助验证类似的情况。我使用waitcondition同步同一线程中的两个方法,run方法和另一个异步调用的方法。子线程在其父线程的构造函数中实例化,但我试图从主线程实例化它,但没有任何结果。我尝试了objectName来验证它,子线程是另一个线程。你知道它为什么这样工作吗?run方法应该在新构造的线程中运行。然后需要从不同的线程(可能是UI线程)调用method1。这将导致调用method1的线程等待run方法将其唤醒。如果waitcondition和wait是从同一个线程调用的,那么它将不起作用。你能发布一个工作示例吗?Brett,我在文章中添加了测试项目。你是对的,我在测试项目中的错误是在exec方法之前调用了write函数。实际上,这解决了测试项目中的问题。但这只表明我不能在测试项目中复制这个问题。我仔细检查了我原来的问题,它在调用任何其他调用之前调用了exec方法。关于附加线程,我还不完全清楚,你能解释一下为什么pparent需要一个附加线程来运行这个类吗?我修复了在exec之后调用write方法的测试,带有一个计时器,只是为了测试目的。我为这个问题添加了一些新的信息。我想我知道我的问题是什么,我正在解决这个问题。pparent不需要移动到单独的线程,但是pparent->write()被阻塞了,所以我的第一个想法是从不同的线程启动ppthread。你也用定时器做了同样的事。我还测试了没有QWaitCondition的版本(我刚刚使用了msleep),以确保QWaitCondition不是这里的问题,并且我得到了相同的结果。还有一件事,请注意,如果您想从不同的线程发送信号,那么需要从具有事件循环的线程创建这样的线程对象,也许你在最初的项目中也有类似的问题。