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

时间:2015-12-13 15:07:59

标签: c++ multithreading qt

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

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

我有类,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);

还有一个信号我传递了实际的const类引用:

void   INFO_UPDATE(const COMInfo& comInfo);

1 个答案:

答案 0 :(得分:1)

&#34;如果QT由本机类型组成,那么QT是否对该类执行原子操作&#34; - 语言是C ++,Qt只是一个库。因此,当从多个线程访问变量并且通常的C ++多线程规则及其内存模型(因为C ++ 11)适用时,Qt不会做任何魔术。然而,信号/插槽机制实现了用于线程间通信的消息传递机制:Queued connections(另请参阅thread synchronisation上的页面)将参数从一个线程传递到另一个线程复制它们。即,传递值类型(如QString,int,double)是安全的 - 接收线程将对发送线程数据的副本进行操作,并且不存在需要锁定的并发访问。 const引用传递的信号/槽参数也将被信号/槽系统复制。

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

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