zoukankan      html  css  js  c++  java
  • Qt跨线程调用错误解析及解决办法

    错误提示:Error: Cannot create children for a parent that is in a different thread.

    错误案例分析

    新建SerialLink子线程,继承QThread,并重写它的run(),调用 start()函数时自动调用重载的run()函数。在主线程中创建SerialLink类的对象。

    串口_port在SerialLink的头文件中定义,在_hardwareConnect()函数中初始化。在_connect()函数中调用start()函数启动线程,自动调用重载的run()函数。

    Class SerialLink: public QThread
    { 
    ……
    QSerialPort* _port;
     ……	
    }
    
    void SerialLink:: _hardwareConnect( )
    {
    ……
    _port = new SerialPort( );
    ……
    }
    
    void SerialLink:: _connect( )
    {
    ……
    _hardwareConnect( );
    start( );
    ……
    }
    
    void SerialLink:: run( )
    {
    ……
    }
    

      该错误是跨线程调用引起的。

          原因:_port的初始化是在SerialLink类中,SerialLink子线程是在主线程中创建的子线程,在SerialLink对象本身工作在主线程下,其中定义的所有东西都属于创建SerialLink的线程,即主线程,所以_port应该是属于主线程(父线程)的;只有run()范围内的代码工作在次线程中,所以在SerialLink的run()中调用_port属于跨线程调用,就会出现异常。

          解决办法:_portrun函数中初始化,_port就是在同一子线程中创建和调用,不会出现跨线程调用错误。

    void SerialLink* run( )
    {
    _hardwareConnect( );
    ……
    }
    void SerialLink* _connect( )
    {
    ……
    start( );
    ……
    }
    void _hardwareConnect( )
    {
    ……
    _port = new SerialPort( );
    ……
    }

    总结

    Thread对象本身工作在主线程下,即使调用其定义的变量和方法,也是工作在主线程下,只有run()范围内的代码才工作在子线程中。为避免跨线程调用引起异常,一个对象的创建和调用要放在同一线程中。

    推荐的工作方式:利用Qt的事件驱动特性,将需要在次线程中处理的业务放在独立的模块(类)中,由主线程创建完该对象后,将其移交给指定的线程,且可以将多个类似的对象移交给同一个线程。

    connect连接类型:

     1) 自动连接(AutoConnection),默认的连接方式,如果信号与槽,也就是发送者与接受者在同一线程,等同于直接连接;如果发送者与接受者处在不同线程,等同于队列连接。

    2) 直接连接(DirectConnection),当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行。

    3) 队列连接(QueuedConnection),当控制权回到接受者所在线程的事件循环时,槽函数被调用。槽函数在接受者所在线程执行。

    在GUI程序中,主线程也叫GUI线程,因为它是唯一被允许执行GUI相关操作的线程。对于一些耗时的操作,如果放在主线程中,就会出现界面无法响应的问题。这种问题的一种解决方式是,把这些耗时操作放到子线程中。

     

  • 相关阅读:
    深入了解JVM-方法区
    Mysql性能调优
    基督教 犹太  新教  东正教 天主教
    caffe的matlab接口一览表
    ubuntu下 编译Caffe的Matlab接口
    Linux入门学习教程:虚拟机体验之KVM篇
    利用proxychains在终端使用socks5代理
    process lasso 优化原理
    解决win7和ubuntu双系统ubuntu不能上网的问题
    调试minix内核
  • 原文地址:https://www.cnblogs.com/warrior1988/p/5358987.html
Copyright © 2011-2022 走看看