Имеется программа, которая выполняет следующие действия,
динамически выделяется оперативная память для хранения очень большого массива данных далее эти данные по сети посылаются в другой компутер,,, При передаче данных по сети вся система начинает тормозить. программу невозможно закрыть до тех пор пока не закончится эта передача .,,,
В общем посоветовали мне передачу данных организовать не в основном потоке...
поскольку опыта программирования у меня почти нет - приходиться учиться по ходу дела буду всем признательна за помощь
поможет ли избавиться от "тормозов" организация многопоточности - может есть какие то решения по-проще?
Далее вопрос про сам принцип организации этой многопоточности
в книге пишут,что нужно создать класс QThread и перезаписать в нем виртуальный метод run(), в котором должен быть реализован код, который будет исполняться в потоке
class MyThread:public QThread
{
public:
void run()
{
код исполняемый в потоке
}
}
Спасибо за разъяснения. Я примерно так и предполагала.
А вот как быть с самой реализацией второго потока?
Почитала про дружественные функции - может это поможет объединить объекты двух классов, или делать дружественные классы? Или я ошибаюсь?
Это мне понятно, а как в этом классе QThread использовать мой массив, к которому я обращаюсь в базовом классе через указатель? Имеет ли значение то,что массив хранится в оперативной памяти и используется еще и в других функциях базового класса? Как сделать, чтобы остальные переменные были "видны" в классе QThread с теми же значениями, которые они принимают в базовом классе?
Прошу прощения за глупые вопросы, мне еще никогда не приходилось работать с двумя классами
PVGDRK, заведи в классе потока приватную член -переменную указатель на основной класс приложения (или всего, что потребуется). Заведи также публичную функцию для настройки указателей. И, главное, не забывай о синхронизации доступа к данным при многопоточности
Ох, спасибо Про переменные почитаю - спасибо ,что сказали, как они называются. А вот про синхронизацию в ООП впервые слышу
Как то до этого больше с железяками возилась
PVGDRK, железки - обычно однопоточные, поэтому в них про синхронизацию не задумываешься )
про переменные - будет нечто вроде
//это некий класс, где храниться массив и так далее
class CMyClass
{
};
class MyThread:public QThread
{
CMyClass* m_pDataKeeper;
public:
MyThread(CMyClass* m_pDataKeeper=0):m_pDataKeeper(m_pDataKeeper)
{
}
//тут ещё, может быть, методы
//....
void run()
{
if(m_pDataKeeper)
{
m_pDataKeeper->....;
}
код исполняемый в потоке
}
}
Спасибо большое за разъяснения. В понедельник буду разбираться дальше
а в выходные не будешь ? )
Не , в выходные не получится - нет сети дома, да и компа того нет, он специфический, да и данные тоже специфические
Почитайте http://doc.qt.nokia.com/qq/qq27-responsive-guis.html
Mercie beaucoup ( Большое спасибо ) Заодно и английский подучу
Простите меня бестолковую, пожалуйста, помогите понять что к чему (я еще и сам С++ практически не знаю)
Написала так как Вы тут привели в примере - на место фразы "код,исполняемый в потоке" вставляю свой код с переменными из класса СMyClass - компилятор ругается пишет типа неизвестная переменная...
Не могли бы Вы мне помочь понять что к чему?
Что означает запись в Вашем примере,
MyThread(CMyClass* m_pDataKeeper=0):m_pDataKeeper(m_pDataKeeper)
{
}
if(m_pDataKeeper)
{
m_pDataKeeper->....;
}
MyThread(CMyClass* pDK=0):m_pDataKeeper(pDK)
{
}
extern "C" __declspec (dllimport) int Create30000000(WaveformDataReal **bS); // Функции написанные в DLL файле
extern "C" __declspec (dllimport) int Add30000000(FILE *fin,float freq, float SNR);
Generator::Generator(QWidget *parent, Qt::WFlags flags) // Конструктор
: QMainWindow(parent, flags)
{
ui.setupUi(this);
createFilesTable();
Disable();
}
Generator::~Generator() // Деструктор
{
CloseAWG();
}
//Далее идут функции и обработчики соединения сигнал слот
.......
//Один из них:
void Generator::on_pushButton_5_clicked()
{
int t=0;
int n=0;
int p=0;
int x1,x2,y1,y2;
QString str_filename;
QString str_txt;
QByteArray ar;
char* datatext;
char str[128];
WaveformDataReal *bS; // bS - это тот массив,который находится в оперативной памяти
float freq, SNR;
FILE *F_1;
bool ok;
float Value=0;
,,,,,,
// Далее как я понимаю идет функция формирования этого массива путем обращения к
// Create30000000(&bS) и Add30000000(F_1, freq, SNR)
// Далее данные из сформированного массива можно либо отправить по сети, либо сохранить в файл...
// Я пока пытаюсь в потоке QThread выполнить сохранение в файл поэтому вот этот код вставляю в потоке QThread
if(ui.checkBox_File->checkState()==Qt::Checked) // Запись в файл
{
if(pPBar!=NULL) pPBar->setWindowTitle(tr("Write file"));
FILE *F_2;
str_txt = ui.lineEdit_NameF->text();
ar = str_txt.toAscii();
datatext=ar.data();
F_2=fopen(datatext,"wb");
for(int j=0;j<100;j++)
{
fwrite((bS+j*300000),sizeof(WaveformDataReal),300000,F_2);
if(pPBar!=NULL) pPBar->setValue(j);
Sleep(10);
}
fclose(F_2);
}
}
//Далее пишу
class MyThread:public QThread
{
Generator*m_pData;
public:
MyThread(Generator*m_pData=0):m_pData(m_pData) // Здесь очевидно ошибка из-за моего непонимания m_pData - указатель н а мой класс или какая то переменная или функция из класса Generator?
{
}
void run() //Если в этой функции не писать ниже приведенный код - то все компилируется, а скодом ругается на переменные что они не определены ... а как правильно все это пишется я не знаю
{
if(m_pData)
{
m_pData-> // здесь не совсем поняла,что нужно писать поэтому ничего не писала
}
if(ui.checkBox_File->checkState()==Qt::Checked) // Запись в файл
{
if(pPBar!=NULL) pPBar->setWindowTitle(tr("Write file"));
FILE *F_2;
str_txt = ui.lineEdit_NameF->text();
ar = str_txt.toAscii();
datatext=ar.data();
F_2=fopen(datatext,"wb");
for(int j=0;j<100;j++)
{
fwrite((bS+j*300000),sizeof(WaveformDataReal),300000,F_2);
if(pPBar!=NULL) pPBar->setValue(j);
Sleep(10);
}
fclose(F_2);
}
}
а где у тебя экземпляр MyThread создаётся ?
по меньшей мере к ui доступ будет так
m_pData->ui
Да к ui доступ есть псоле записи ui. выпадает список всего того. что размещено у меня на форме и есть еще какието setupUi b retranslateUi....
PVGDRK, так, стоп! "какие-то" - это именно принадлежащие ui.
Всё-таки, ответь на вопрос
Не, я так понимаю совсем не в конструкторе моего генератора если посмотреть на выше приведенный код , то экземпляр MyThread создаётся где то в самом низу в файле generator.cpp....
Я правильно понимаю. что экземпляр MyThread нужно создать вот здесь?
Файл generator.cpp
Generator::Generator(QWidget *parent, Qt::WFlags flags) /[u][b]/ Конструктор[/b][/u]
: QMainWindow(parent, flags)
{
ui.setupUi(this);
createFilesTable();
Disable();
}
Generator::~Generator() // Деструктор
{
CloseAWG();
}
#ifndef GENERATOR_H
#define GENERATOR_H
#include....
......
class Generator : public QMainWindow
{
Q_OBJECT
public:
Generator(QWidget *parent = 0, Qt::WFlags flags = 0);
~Generator();
QString data[100];
ViSession rm, vi;
ViStatus status;
char buffer_1[BUFSIZ];
ViUInt32 retCount;
bool OpenAWG;
public:
Ui::GeneratorClass ui;
QTableWidget *filesTable;
void CloseAWG(void);
void ReadWaveFormData(void);
void ReadSetting(void);
void Enable(void);
void Disable(void);
public slots:
void createFilesTable();
void on_pushButton_5_clicked();
void on_pushButton_3_clicked();
void on_tableWidget_cellDoubleClicked(int Col, int Row);
void on_pushButton_2_clicked();
private slots:
void on_tabWidget_currentChanged(int);
void on_comboBox_2_textChanged(const QString &);
void on_lineEdit_NameF_textChanged(const QString &);
void on_pushButton_8_clicked();
void on_comboBox_textChanged(const QString &);
void on_pushButton_4_clicked();
void on_pushButton_7_clicked();
void on_lcdNumber_overflow();
void on_pushButton_6_clicked();
void on_pushButton_clicked();
};
#endif // GENERATOR_H
PVGDRK, поиском я не нашёл, где у тебя создаётся экземпляр MyThread. Может, ты не весь код показала ?
Или "внизу файла" - это ты говоришь про ОПИСАНИЕ класса
class MyThread:public QThread
{
Я так понимаю у меня вообще не создается экземпляр класса QThread
Проект в личку отправлю
Если я все вырежу - то Вы мне тогда не сможете помочь
Эх, у нас тут на работе настройки инета такие, что мне ни сюда ни в личку ничего не загрузить
PVGDRK, ладно, щас набросаю схемку. Но! Срочно читать книжки по C++!!! Про классы.
Так я читаю - видно плохо понимаю что пишут... в книге 850 страниц я пока на 44
файл MyThread.h
#pragma once
#include <QThread>
class Generator;
class MyThread:public QThread
{
Generator* m_pData;
public:
MyThread(Generator* pData=0);
virtual void run();
};
#include "MyThread"
MyThread::MyThread(Generator* pData)
:m_pData(pData)
{
}
void MyThread::run()
{
}
#pragma once
#include <QMainWindow>
class MyThread;
class Generator : public QMainWindow
{
Q_OBJECT
MyThread* m_pTHREAD;
public:
Generator(QWidget *parent = 0, Qt::WFlags flags = 0);
~Generator();
...
...
};
#include "Generator"
#include "MyThread"
Generator::Generator(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
createFilesTable();
Disable();
m_pTHREAD=new MyThread(this);
}
Безмерно Вам благодарна за подробный ответ
Нечто подобное я пыталась написать , но видимо что то не так сделала и не помогло, а потом вообще запуталась что где пишется и в каких файлах - в моей книжке про это ничего не пишут... вот решила обратиться за помощью на форум...
Спасибо Вам большое еще раз. попробую сейчас реализовать это
Помогите теперь, пожалуйста понять, как это работает ...
с горем по-полам что то написала
в файле main.cpp дописала пару строк:
MyThread thread;
thread.start();
if (m_pData-> что тут не знаю )
if (m_pData)
{
m_pData->on_pushButton_5_clicked();
}
Да при нажатии на кнопку pushButton_5 в другом потоке должны выполниться определенные действия,
я пока тупо все что делается в обработчике сигнала on_pushButton_5_clicked(); хочу сделать в другом потоке, т,к. не совсем понимаю как выполнить часть действий в частности потому.что не знаю как обратиться к некотороым функциям, которые у меня импортировааны из dll....
так они у меня и так в cpp файле генератора описаны. но до конструктора ...
а в каком виде их нужно писать в файле потока?
int Create30000000(WaveformDataReal **bS)
{ а тут тогда что писать?
}
PVGDRK, "до конструктора" - это, я так понимаю, на твоём языке означает "не член класса и расположен в cpp-файле"
тут выхода по меньшей мере два:
1) если не хочешь из cpp убирать, сделай в Generator функцию-трамплин.
2) или же сделай Create30000000 статической функцией класса Generator
Спасибо Вам добрый человек за терпение и внимание к моим дурацким вопросам
Испытываю непередвавемые ощущения от осознания того, что нормальные люди пишут это минут за 15 а я за 2 недели и то не могу написать
PVGDRK, я на самом деле злой, я ж из Обливиона ))
А скорость разработки - это всего лишь опыт и количество практики. Придёт и к тебе Ты достаточно упорная для этого
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)