Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Надёжность сигналов-слотов


Автор: Lindemann66 18.10.2011, 10:10
Всем привет!

Представьте
Программа, выполняющая сканирование сайтов на предмет обновлений
Допустим, в БД 50 сайтов = 50 сканирующих "потоков"...
В каждом "потоке" - скачка html-кода из интернета, парсинг, внесение в БД...

Я специально закавычил слово "поток", потому что, в данном случае, использование потоков не обязательно...

Важно другое

Как организовать такую работу наиболее правильным "архитектурно-технологически" способом?
Мне просто интересны варианты smile

Уже пробовал создавать отдельный поток под каждый сайт, но проблема в том, что сканирование сайтов (читай - использование QWebPage) необходимо делать в главном (GUI) потоке
К тому же, этот механизм не показал особой стабильности...
Может, из-за корявости реализации, не использования QthreadPool'ов (ксттаи, интересно, насколько хорош QThreadPool))

Сейчас делаю так...(просто пример, но суть работы та же, что и в программе)
Analyzer
Код

class Analyzer : public QObject {
    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[i];
    }
}

void Analyzer::analyze(QString str) {
    qDebug() << "Timer " + str;
}


Timer
Код

class Timer : public QObject {
    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. Ну и вообще, Ваше мнение на сей счёт

Вопросов много накатал...
Буду рад, если кто-нибудь ответит smile

Автор: Artemon 22.10.2011, 13:09
А для чего использовать QWebPage ?

Если использовать Qt, то ябы сделал так: По количеству сайтов создалбы объекты QHttp запросы от данного объекта выполняются асинхронно и не блокирует основной поток. Поэтому запускаем получение данных, когда данные приходят - QHttp вызывает соответствующие слоты.

Далее вторая часть:

Из слота можно создавать поток, передавать в него полученный Html текст, запускать поток на выполнение и забывать о нем (конечноже не забыв сделать чтобы он атоматически удалялся для этот смотрим deleteLater).

Ну а в потоке делать уже парсинг и сохранение полученных данных в БД.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)