QT 4.3在线程之间传递类指针

QT 4.3 passing class pointer between threads

本文关键字:指针 之间 线程 QT      更新时间:2023-10-16

我正在使用QT 4.3.1(遗留代码必须使用它),并且我正在使用信号和插槽在工作线程和GUI线程之间传递类引用。

如果该类由本机类型(Qstring、int、unsigned char)组成,QT是否对此类执行原子操作,或者我仍然需要QMutex?在线程之间传递类或数据缓冲区的引用是否安全,或者是否有更好的方法来共享它并防止并发访问?

我有一个类,COMinfo由另一个类和一个使用本机类型的结构组成:

typedef struct Port_Check_Struct
{
    U_BYTE  command       :4;
    U_BYTE  spare15_4   :2; /* spare bits */
    U_BYTE  status       :2; 
} PORT_CHECK_STRUCT;

class PortInfo
{
public:
    PortInfo();
    QString     portName;
    U_BYTE      Dir;
    UNSIGNED16  Addr;
    U_BYTE      Size;
    bool        active;
    U_BYTE      lastused;
    U_BYTE      currused;
    U_BYTE      errorCntr;
    U_BYTE      portBuff[100];
    U_BYTE      dataBuff[100];
    PORT_CHECK_STRUCT   *portCheck;
};

class COMInfo
{
public:
    UNSIGNED8   errorStatus;
    UNSIGNED16  COMaddr;
    PortInfo    portInfo[4];
};
    // Define Meta Types for SIGNAL/SLOT CROSS THREAD TYPES
    qRegisterMetaType<COMInfo>("COMInfo");

我使用qRegisterMetaType()将数据类型注册到MOC。

我在我的工作线程和GUI线程之间传递引用,如下所示:

emit COM_DATA_UPDATE(COM_Info.portInfo[0].dataBuff)

QT与此参考文献有什么关系?这是一个肤浅的复制品吗?需要复制构造函数吗?

信号定义为:

void   COM_DATA_UPDATE(const U_BYTE* msg);

还有一个信号我通过实际常量类引用:

void   INFO_UPDATE(const COMInfo& comInfo);

"如果QT由本机类型组成,它会对这个类执行原子操作吗?"-语言是C++,QT只是一个库。因此,当从多个线程访问变量时,Qt没有任何魔力,并且通常的C++多线程规则及其内存模型(自C++11以来)适用。然而,信号/槽机制实现了线程间通信的消息传递机制:排队连接(另请参阅线程同步页面)通过复制参数将参数从一个线程传递到另一个线程。也就是说,传递QString、int、double等值类型是安全的——接收线程将对发送线程的数据副本进行操作,并且不存在需要锁定的并发访问。const引用传递的Signal/Slot参数也将被信号/插槽系统复制。

但是,如果将指针作为参数或包含在结构中传递,则指针将被复制,而不是它所指向的对象(在没有自定义复制ctor/assignment运算符实现的情况下)。因此,访问传递的指针对来说是不安全的,并且您需要一个同步机制,如互斥锁。

在您的示例中,PORT_CHECK_STRUCT *portCheck(在传递PortInfo对象时)和void COM_DATA_UPDATE(const U_BYTE* msg)都存在此问题。我建议通过std::array(或者std::vector/QVector,如果不能使用C++11)传递数据。