Поиск:

Ответ в темуСоздание новой темы Создание опроса
> QThread бесконечные циклы, Как обеспечить работу бесконечных циклов 
:(
    Опции темы
Lindemann66
  Дата 7.9.2011, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Thinking...
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 2.8.2011
Где: Ульяновск

Репутация: нет
Всего: нет



Всем привет!

У меня такой, возможно, глупый вопрос
Следующий код:
Заголовочные файлы
Код

//класс, выдающий сообщение в консоль
class Event {
public:
    void Show(QString str);
};

//класс главного потока
class MainThread {
private:
    Event *m_event;
public:
    MainThread();
    ~MainThread();
    void Run();
};

//класс второстепенного потока
class ChildThread : public QThread {
Q_OBJECT
private:
    Event *m_event;
    uint m_number;
public:
    void setNumber(uint number);
    void setEvent(Event *event);
    void run();
};


Реализация
Код

#include "Classes.h"

void Event::Show(QString str) {
    qDebug() << str;
}

MainThread::MainThread() {
    m_event = new Event();
}

MainThread::~MainThread() {
    delete m_event;
}

void MainThread::Run() {
    for (int i = 0; i < 10; i++) {
        ChildThread child;
        child.setNumber(i);
        child.setEvent(m_event);
        child.run();
    }
}

void ChildThread::setNumber(uint number) {
    m_number = number;
}

void ChildThread::setEvent(Event *event) {
    m_event = event;
}

void ChildThread::run() {
    while (true) {
        m_event->Show(QString("Run from %1 thread").arg(m_number));

        sleep(3);
    }
}




Суть
Нужно создать определённое число потоков (10 в данном примере)
И вызывать внутри каждого некую операцию (в данном случае - qDebug)

Проблема
Программа доходит до бесконечного цикла первого потока, и в нём и остаётся

Как можно сделать так, чтобы проинициализировались все 10 бесконечных циклов, и продолжали работу?

Буду очень благодарен за любые ответы smile

Это сообщение отредактировал(а) Lindemann66 - 7.9.2011, 09:32
--------------------
stay true
PM MAIL WWW ICQ   Вверх
alexvs11
Дата 7.9.2011, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



start()
PM MAIL   Вверх
borisbn
Дата 7.9.2011, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Lindemann66, ты не создаёшь ни одного потока. То, что твой класс называется ChildThread и то, что он наследован от QThread - ещё не значит, что ты создаёшь поток. Сделай так:

Код

class MainThread {
private:
    Event *m_event;
    std::vector< ChildThread * > m_threads;
public:
    MainThread();
    ~MainThread();
    void Run();
};

class ChildThread : public QThread {
Q_OBJECT
private:
    Event *m_event;
    uint m_number;
    bool m_keepRun;
public:
    ChildThread() : m_keepRun( true ) {}
    void setNumber(uint number);
    void setEvent(Event *event);
    void run();
    void stop() { m_keepRun = false; }
};


MainThread::MainThread() {
    m_event = new Event();
    for ( int i = 0; i < 10; i++ ) {
        ChildThread * thread = new ChildThread();
        thread->setNumber( i );
        thread->setEvent( m_event );
        m_threads.push_back( thread );
    }
}

MainThread::~MainThread() {
    foreach ( const QThread * thread, m_threads ) {
        thread->stop();
        thread->wait();
        delete thread;
    }
    delete m_event;
}
void MainThread::Run() {
    foreach ( const QThread * thread, m_threads ) {
        thread->start();
    }
}

void ChildThread::run() {
    while ( m_keepRun ) {
        m_event->Show(QString("Run from %1 thread").arg(m_number));
        sleep(3);
    }
}


и ещё (просто замечание по стилю) - обычно принято интерфейс класса (секция public) выносить в начало описания, а внутренности, нужные только самому классу (секция private) - в конец. У тебя же наоборот.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alca
Дата 7.9.2011, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Цитата

и ещё (просто замечание по стилю) - обычно принято интерфейс класса (секция public) выносить в начало описания, а внутренности, нужные только самому классу (секция private) - в конец. У тебя же наоборот.

А как же порядок инициализации членов класса?  smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Lindemann66
Дата 7.9.2011, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Thinking...
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 2.8.2011
Где: Ульяновск

Репутация: нет
Всего: нет



Спасибо за ответыsmile
Почитав их, а также документацию, сделал так, как написано ниже:
Заголовочный файл
Код
//класс, выдающий сообщение в консоль
class Event {
public:
    void Show(QString str);
};

//класс второстепенного потока
class ChildThread : public QThread {
Q_OBJECT
public:
    ChildThread(QObject *parent = 0);
    void setNumber(uint number);
    void setEvent(Event *event);
protected:
    void timerEvent(QTimerEvent *event);
private:
    Event *m_event;
    uint m_number;
};

//класс главного потока
class MainThread {
public:
    MainThread();
    ~MainThread();
    void Run();
private:
    Event *m_event;
    QList<ChildThread *> threads;
};


Реализация
Код

void Event::Show(QString str) {
    qDebug() << str;
}

MainThread::MainThread() {
    m_event = new Event();
}

MainThread::~MainThread() {
    delete m_event;
    for (int i = 0; i < 3; i++) {
        delete threads[i];
    }
}

void MainThread::Run() {
    for (int i = 0; i < 3; i++) {
        ChildThread *child = new ChildThread();
        child->setNumber(i);
        child->setEvent(m_event);
        threads.push_back(child);
        child->start();
    }
}

ChildThread::ChildThread(QObject *parent) : QThread(parent) {
    startTimer(1000);
}

void ChildThread::setNumber(uint number) {
    m_number = number;
}

void ChildThread::setEvent(Event *event) {
    m_event = event;
}

void ChildThread::timerEvent(QTimerEvent *event) {
    m_number++;
    m_event->Show(QString("Run from %1 thread").arg(m_number));
}


Добавлено через 2 минуты и 5 секунд
Цитата(Alca @  7.9.2011,  10:40 Найти цитируемый пост)
А как же порядок инициализации членов класса?

А что с ними?)
--------------------
stay true
PM MAIL WWW ICQ   Вверх
Alca
Дата 7.9.2011, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Цитата

А что с ними?)

Инициализаци - сверху вниз


--------------------
PM WWW ICQ Skype Jabber   Вверх
borisbn
Дата 7.9.2011, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Lindemann66, у тебя не определено тело основной функции потока. А в случае с таймером наследоваться от QThread - вообще необязательно, как и вызывать start().
Ты попробовал как я тебе написал ?

Цитата(Alca @  7.9.2011,  10:40 Найти цитируемый пост)
А как же порядок инициализации членов класса?

Члены класса (переменные, а не ф-ции) в public - вообще зло.
А за такое
Код

class X {
public:
    int x;
    X() : y(x ), x( 0 ) {} 
private:
    int y;
}

ты бы, наверное, и сам руки бы оторвал


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alca
Дата 7.9.2011, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



Цитата

Члены класса (переменные, а не ф-ции) в public - вообще зло.

а если переменных много ( порядка 10-20) ? Делать для каждой по два метода (get, set) и по свойству?
Чего-то геморно...

Это сообщение отредактировал(а) Alca - 7.9.2011, 13:08


--------------------
PM WWW ICQ Skype Jabber   Вверх
borisbn
Дата 7.9.2011, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(Alca @  7.9.2011,  13:07 Найти цитируемый пост)
а если переменных много ( порядка 10-20) ? Делать для каждой по два метода (get, set) и по свойству?

я себе для этого в VisualAssistant'е сделал snippet. А раньше (да и щаз иногда) делал макрос
Код

#define GETSET(type, name) \
public: \
    type name() const {return m_##name;} \
    void set##name##(type value){m_##name=value;} \
protected: \
    type m_##name




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alca
Дата 7.9.2011, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



borisbn,  я  имею ввиду, что объем код начинает увеличиваться со страшной силой

Добавлено через 15 секунд
Впадло скролить 


--------------------
PM WWW ICQ Skype Jabber   Вверх
spyswamp
Дата 7.9.2011, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Alca, значит это очень плохой класс, который содержит в себе 10-20 переменных-членов, которые надо куда-то выдавать. Говорит лишь о проблеме дизайна, не более.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
Alca
Дата 7.9.2011, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50





--------------------
PM WWW ICQ Skype Jabber   Вверх
Lindemann66
Дата 8.9.2011, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Thinking...
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 2.8.2011
Где: Ульяновск

Репутация: нет
Всего: нет



Цитата(borisbn @  7.9.2011,  13:01 Найти цитируемый пост)
Ты попробовал как я тебе написал ?

Да, попробовалsmile
Респект

Единственно, не сработало
Код

foreach ( const QThread * thread, m_threads ) {
        thread->start();
    }

ругается на QThread (в 2ух местах, где foreach)
Цитата

error: 'const class QThread' has no member named 'stop'
error: passing 'const QThread' as 'this' argument of 'bool QThread::wait(long unsigned int)' discards qualifiers
error: passing 'const QThread' as 'this' argument of 'void QThread::start(QThread::Priority)' discards qualifiers


Поэтому заменил на
Код

foreach ( ChildThread *thread, m_threads ) {
        thread->start();
    }


Теперь буду пробовать прикрутить мутексы

Добавлено @ 13:00
Цитата(borisbn @  7.9.2011,  13:01 Найти цитируемый пост)
Код

class X {
public:
    int x;
    X() : y(x ), x( 0 ) {} 
private:
    int y;
}
ты бы, наверное, и сам руки бы оторвал

да!
 smile

Цитата(borisbn @  7.9.2011,  13:13 Найти цитируемый пост)
А раньше (да и щаз иногда) делал макрос

красиво
Тоже так делаю

Добавлено @ 13:08
Кстати, не подскажешь, как в твоём коде сделать так, чтобы операция действия с каждым event (там вывод в консоль выполняется) блокировалась мутексом?
Если, например, будет
Код

void ChildThread::run() {
    while ( m_keepRun ) {
        m_event->Show(QString("Run from %1 thread (1)").arg(m_number));
        sleep(m_number);
        m_event->Show(QString("Run from %1 thread (2)").arg(m_number));
        sleep(m_number);
        m_event->Show(QString("Run from %1 thread (3)").arg(m_number));
        sleep(m_number);
    }
}


Это сообщение отредактировал(а) Lindemann66 - 8.9.2011, 13:14
--------------------
stay true
PM MAIL WWW ICQ   Вверх
borisbn
Дата 8.9.2011, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(Lindemann66 @  8.9.2011,  12:56 Найти цитируемый пост)
Кстати, не подскажешь, как в твоём коде сделать так, чтобы операция действия с каждым event (там вывод в консоль выполняется) блокировалась мутексом?

Код

class Event {
public:
    void Show(QString str);
private:
    QMutex m_mutex;
};

void Event::Show(QString str) {
    QMutexLocker( & m_mutex );
    qDebug() << str;
}



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Lindemann66
Дата 8.9.2011, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Thinking...
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 2.8.2011
Где: Ульяновск

Репутация: нет
Всего: нет



Спасибоsmile
только если вот так написать QMutexLocker(&m_mutex);, то будет ошибка
Цитата

error: 'm_mutex' declared as reference but not initialized

Я вот так написал QMutexLocker locker(&m_mutex);
Без ошибок собралось


Это сообщение отредактировал(а) Lindemann66 - 8.9.2011, 13:46
--------------------
stay true
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0552 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.