у меня много вопросов по поводу QThread и потоков. У меня есть класс ClassData, который в конструкторе принимает два массива данных, затем передает эти данные классу ClassDataWorker, который в отдельном потоке обрабатывает данные и возвращает их обратно. При этом во время работы ClassDataWorker к ClassData могут обращаться другие обьекты с помощью getData(). В общем хочу сделать подгрузку данных в потоке чтобы не фризить интрефейс.
class ClassData: public QObject
{
Q_OBJECT
public:
explicit ClassData(QSharedPointer<QVarLengthArray<uint8_t> > data,
QSharedPointer<QVarLengthArray<uint64_t> > dataF,
uint8_t unitsize, QObject *parent=0);
~ClassData();
void getData(std::vector<std::pair<uint64_t,uint8_t>> *data,...);
ClassDataWorker* worker;
private:
struct MipMapLevel
{
QSharedPointer<QVarLengthArray<uint8_t> > _data;
QSharedPointer<QVarLengthArray<uint64_t> > _dataF;
};
QSharedPointer<QVarLengthArray<uint8_t> > _data;
QSharedPointer<QVarLengthArray<uint64_t> > _dataF;
QSharedPointer<QVarLengthArray<uint8_t>> _curData;
QSharedPointer<QVarLengthArray<uint64_t> > _curDataF;
QThread thread_a;
struct MipMapLevel mip_map_[10];
public slots:
void recvData(QSharedPointer<QVector<ClassDataWorker::MipMapLevel>> data);
void lastDataAppend();
};
ClassData::ClassData(QSharedPointer<QVarLengthArray<uint8_t> > data, QSharedPointer<QVarLengthArray<uint64_t> > dataF, QObject
*parent)
: QObject(parent),
_data(data),
_dataF(dataF)
{
memset(mip_map_, 0, sizeof(mip_map_));
mip_map_[0]._data = _data;
mip_map_[0]._dataF = dataF;
_curData = mip_map_[0]._data;
_curDataF = mip_map_[0]._dataF;
for(uint8_t i=1;i<ScaleStepCount;++i){
mip_map_[i]._data = QSharedPointer<QVarLengthArray<uint8_t>>(new QVarLengthArray<uint8_t> );
mip_map_[i]._dataF = QSharedPointer<QVarLengthArray<uint64_t> >(new QVarLengthArray<uint64_t> );
}
qRegisterMetaType< QSharedPointer<QVector<ClassDataWorker::MipMapLevel>>
>("QSharedPointer<QVector<ClassDataWorker::MipMapLevel>>");
worker = new ClassDataWorker(_data,_dataF,_unitsize);
connect(worker, &ClassDataWorker::newData,
this, &ClassData::recvData,Qt::QueuedConnection);
connect(worker, &ClassDataWorker::dataEnded,
this, &ClassData::lastDataAppend,Qt::QueuedConnection);
connect(&thread_a, &QThread::started, worker, &ClassDataWorker::run);
worker->moveToThread(&thread_a);
thread_a.start();
}
void ClassData::lastDataAppend(){
thread_a.quit();
// thread_a.wait();
delete worker;
}
void ClassData::recvData(QSharedPointer<QVector<ClassDataWorker::MipMapLevel> > data){
for(uint8_t level = 1; level < 10;++level){
auto data_ = (data->begin()+level)->_data;
auto dataF_ = (data->begin()+level)->_dataF;
// mip_map_[level]._data->reserve(mip_map_[level]._data->size() + data_.size());
// mip_map_[level]._dataF->reserve(mip_map_[level]._dataF->size() + dataF_.size());
for(int i=0;i<dataF_.size();++i){
mip_map_[level].dataF_->append(*(dataF_.begin()+i));
}
for(int i=0;i<data_.size();++i){
mip_map_[level]._data->append(*(data_.begin()+i));
}
}
}
void ClassData::getData(std::vector<std::pair<uint64_t,uint8_t> > *dataP, ...){
_curData = mip_map_[level]._data;
_curDataF = mip_map_[level]._dataF;
int ind = 0;
while(_curData.size()){
dataP->append({_curData[ind],_curDataF[ind]});
++ind;
}
}
ClassDataWorker:
class ClassDataWorker: public QObject{
Q_OBJECT
public:
explicit ClassDataWorker(QSharedPointer<QVarLengthArray<uint8_t> > data,
QSharedPointer<QVarLengthArray<uint64_t> > dataF,
QObject *parent=0);
~ClassDataWorker();
struct MipMapLevel
{
QVarLengthArray<uint8_t> _data;
QVarLengthArray<uint64_t> _dataF;
};
signals:
void newData(QSharedPointer<QVector<ClassDataWorker::MipMapLevel>> data);
void dataEnded();
public slots:
void run();
};
void ClassDataWorker::run(){
QSharedPointer<QVector<MipMapLevel>> mip_map_ = QSharedPointer<QVector<MipMapLevel>>(new QVector<MipMapLevel>);
mip_map_->fill(MipMapLevel(),10);
_curData = &(_data);
_curDataF = &(_dataF);
//чтение _data и _dataF, запись в mip_map_
emit newData(mip_map_);
if(/*все данные обработаны*/)
emit dataEnded();
// чтбы обработать все данные и eventLoop работал правильно
QMetaObject::invokeMethod(this, "run", Qt::QueuedConnection);
}
Правильно ли я использую потоки? Будут ли утечки?
В функции ClassData::recvData() если использовать reserve() при уcловии что приходят данные примерно одинаковой длинны, время копирования увеличивается после каждого вызова recvData почему так происходит?
При этом если не использовать reserve() копирование проходит быстро и за константное время но вызов getData() приводит к ошибке и закрытию программы, наверное надо разделять доступ к mip_map_? Как правильно это сделать?
Любые комментарии, вопросы и критику приветствую, спасибо тем кто дочитал.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
На VDS лежит самописная программка (на С++), при запуске исполняемого бинарника из под root - работает корректноСтоит зайти за другого пользователя...
Пытаюсь реализовать БПФ из Mathcad в проекте на Qt c++ Неполучается интерпретировать данную формулу
Как происходит помещение структур в вектор? Допустим я задал некую структуру
У меня есть компонент для реакта, который описывает элемент <li> спискаЛогика работы компонента такая: он рендерит текст и <span> с крестиком...