2015-12-13 2 views
0

Я использую QT 4.3.1 (код устаревания должен использовать его), и я передаю ссылку класса между моим рабочим потоком и потоком графического интерфейса с использованием сигналов и слотов.QT 4.3 Передача указателя класса между потоками

Выполняет ли QT атомные операции над этим классом, если он состоит из нативных типов (Qstring, int, unsigned char) или мне еще нужен 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().

Я передаю ссылки между моим рабочим и 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); 
+0

атомарность не является составной. Два значения атомарного доступа, соединенные в структуру, не являются совместно атомарными. Атоматичность часто не обеспечивает достаточного потокобезопасного поведения. Безопасность потоков - это функция того, что вы делаете, и, следовательно, какие гарантии вам нужны. Простой способ обеспечения безопасности потоков - никогда не передавать данные, просто копировать. Все остальное имеет тенденцию быть более упрощенным, неправильным, очень сложным или часто одним или всеми тремя. – Yakk

ответ

1

«Имеет ли QT выполнение атомарных операций этого класса, если он состоит из родные типы "- язык C++, Qt - только библиотека. Таким образом, Qt не делает никакой магии, когда к переменным обращаются из нескольких потоков, и применяются обычные правила многопоточности C++ и его модель памяти (начиная с C++ 11). Однако механизм сигнала/слота выполняет сообщение , передающее механизм для межпоточной связи: Queued connections (см. Также страницу на thread synchronisation) передает аргументы из одного потока в другой путем их копирования. I.e, передающие типы значений, такие как QString, int, double являются безопасными - принимающий поток будет работать с копией данных отправляющего потока, и нет параллельного доступа, который требует блокировки. Аргументы Signal/Slot, переданные с помощью ссылки const, также будут скопированы системой сигналов/слотов.

Однако, если вы передаете указатели либо в качестве аргумента или содержащихся в структурах, указателя копируется, а не объект он указует (в том случае, нет пользовательской копии т х р/назначения реализации оператора делает в противном случае). Таким образом, доступ к пройденному указателю равен , а не, и вам понадобится механизм синхронизации, такой как мьютекс.

В вашем примере PORT_CHECK_STRUCT *portCheck имеет эту проблему (при передаче объекта PortInfo), а также void COM_DATA_UPDATE(const U_BYTE* msg). Я бы предложил передать данные через std :: array (или std :: vector/QVector, если вы не можете использовать C++ 11).

+0

Будет ли QT копировать эти типы данных в конструкцию класса, или должен ли мой класс быть получен из QObject? Кроме того, не используя C++ 11, компилятор C++ 98 – zacharoni16

+1

Нет, никогда не используйте QObject для классов значений (его копия ctor и оператор присваивания являются частными по причине). Просто объявите метатип. –

+0

Вопрос только в моем старом коде, как эти указатели работают даже, если у меня нет конструктора копирования? Есть ли глубокие указатели QT с конструктором по умолчанию? – zacharoni16

Смежные вопросы