Надёжность сигналов-слотов
Представьте
Программа, выполняющая сканирование сайтов на предмет обновлений
Допустим, в БД 50 сайтов = 50 сканирующих "потоков"...
В каждом "потоке" - скачка html-кода из интернета, парсинг, внесение в БД...
Я специально закавычил слово "поток", потому что, в данном случае, использование потоков не обязательно...
Важно другое
Как организовать такую работу наиболее правильным "архитектурно-технологически" способом?
Мне просто интересны варианты :)
Уже пробовал создавать отдельный поток под каждый сайт, но проблема в том, что сканирование сайтов (читай - использование QWebPage) необходимо делать в главном (GUI) потоке
К тому же, этот механизм не показал особой стабильности...
Может, из-за корявости реализации, не использования QthreadPool'ов (ксттаи, интересно, насколько хорош QThreadPool))
Сейчас делаю так...(просто пример, но суть работы та же, что и в программе)
Analyzer
Q_OBJECT
public:
Analyzer();
~Analyzer();
public slots:
void analyze(QString str);
private:
QList<Timer *> m_timers;
};
Analyzer::Analyzer() {
//запускаем 100 таймеров
for (int i = 0; i < 100; i++) {
Timer *timer = new Timer(10000, i);
m_timers.push_back(timer);
connect(timer, SIGNAL(analyze(QString)),
this, SLOT(analyze(QString))
);
}
}
Analyzer::~Analyzer() {
for (int i = 0; i < m_timers.size(); i++) {
delete m_timers;
}
}
void Analyzer::analyze(QString str) {
qDebug() << "Timer " + str;
}
Timer
Q_OBJECT
public:
Timer(int interval, int number);
~Timer();
public slots:
void needAnalyze();
signals:
void analyze(QString str);
private:
int m_number;
QTimer *m_timer;
};
Timer::Timer(int interval, int number) {
m_timer = new QTimer(this);
//раз в 10 секунд
m_timer->start(interval);
connect(m_timer, SIGNAL(timeout()),
this, SLOT(needAnalyze())
);
m_number = number;
}
Timer::~Timer() {
m_timer->stop();
delete m_timer;
}
void Timer::needAnalyze() {
emit analyze(QString::number(m_number));
}
То есть, есть класс анализатора, в котором создаются потоки, и каждый из них вызывает через определённое время сигнал о том, что необходимо произвести анализ
То есть, всё построено на механизме сигналов-слотов
Но, при "большом" объёме сайтов (примерно 20-30) - прога заваливается, и либо не сканирует какие-то сайты, либо не работает вообще
И я не могу определить, в чём тут проблема!
То есть, если брать 5 +-5 сайтов, то работа стабильна, а чуть больше - глючит
Дело ли тут в том, что механизм сигналов-слотов даёт сбой, или где-то в алгоритме ошибка (но прога ведь не падает..)?
Отсюда вопросы:
1. Насколько надёжно, на Ваш взгляд, использование механизма сигналов-слотов
2. Насколько оно надёжно в приведённом случае
3. Насколько рнационален, на Ваш взгляд, предложенный мной подход к решению проблемы
4. Ну и вообще, Ваше мнение на сей счёт
Вопросов много накатал...
Буду рад, если кто-нибудь ответит :)
разбить бы на потоки, да вопрос, что там проводить...
Если QWebPage должна быть в GUI!
GUI ведь только в главном потоке, в других не может быть?
Ну это не к нам а к тебе вопрос - мы то хз что ты там делаешь.
агаа )
В Qt события окнам доставляются только в потоке, в котором QApplication::exec выполнен (говорят это должно быть только в main потоке).
QApplication::exec()
Qt Threads Basics говорит:
GUI Thread and Worker Thread
As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a "worker thread" because it is used to offload processing work from the main thread.
2. Таймеры, сколько бы вы их не завели, живут все в том же одном потоке и исполняются последовательно.
3. Перед использованием пула потоков необходимо осознать его предназначение.
QApplication::exec()
Qt Threads Basics говорит:
Думаю все же что будет работать, пусть и в одном но "вторичном" потоке. Естестенно вся инициализация и exec должны быть в нем, коли множественные GUI Threads не поддерживаются. Да только тогда это всякий смысл теряет.
А кто отменил асинхронный ввод/вывод и когда?
Тут я только про Qt GUI, так что я не очень тебя понял
У ТС то решение проблемы заключается в: "наплюй" запросов в основном потоке, а по сигналам завершения засунь результат в очередь/очереди для рабочих потоков(пула потоков) и жуй все параллельно.
PS: Наму амида буцу.