crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V   1 2 3 >  
Ответить в данную темуНачать новую тему
gpepsi
  опции профиля:
сообщение 4.10.2011, 20:37
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


как из потоковой функции можно понять, что ожидается завершение потока ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 5.10.2011, 10:00
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Послать ей сигнал.
Или ввести какую-нибудь переменную, например bool m_bThreadStop = false;, которую периодически проверять.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 5.10.2011, 12:34
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 5.10.2011, 11:00) *
Или ввести какую-нибудь переменную, например bool m_bThreadStop = false;, которую периодически проверять.


у меня куча потоков. для каждой заводить переменную ?

Цитата(ViGOur @ 5.10.2011, 11:00) *
Послать ей сигнал.


а как внутри определить ?

ну если внутри
while(true)
{
}

никак не завершиться. нужно ожидать на чем-то. Странно что этого не предусмотрели...

Сообщение отредактировал gpepsi - 5.10.2011, 12:35
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver47
  опции профиля:
сообщение 5.10.2011, 13:53
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 356
Регистрация: 1.4.2010
Пользователь №: 1584

Спасибо сказали: 40 раз(а)




Репутация:   6  


Цитата(gpepsi @ 5.10.2011, 14:34) *
у меня куча потоков. для каждой заводить переменную ?


Если Вам необходимо тормозить все потоки одновременно, то проще завести одну переменную в главном потоке, а остальным передать указатель на нее.

Чем не подходит QThread::quit() ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 5.10.2011, 15:09
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(silver47 @ 5.10.2011, 14:53) *
Чем не подходит QThread::quit() ?


а как это будет выглядеть ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 5.10.2011, 18:03
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(silver47 @ 5.10.2011, 14:53) *
Чем не подходит QThread::quit() ?


а - понял, что имеется ввиду
 class MyThread : public QThread
 {
 public:
     void run();
 };

 void MyThread::run()
 {
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
 }


в главном потоке
main()
{
   QCoreApplication app(...);
   MyThread th;
   ...
   app.exec();
   ...
   th.quit();
   th.wait();
   return 0;

}


1. Это если все на сигналах построено, а если мне нужно крутить цикл, например, для чтения
while(...)
{
   ReadFile(...);
}


2. Что если слоты подключаются в главном потоке, а сигналы вызываются в дочернем ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver47
  опции профиля:
сообщение 6.10.2011, 5:17
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 356
Регистрация: 1.4.2010
Пользователь №: 1584

Спасибо сказали: 40 раз(а)




Репутация:   6  


Имеется ввиду, что если у вас есть указатели на потоки, то можно вызвать метод QThread::quit(). А проверить есть ли запущенные потоки, кроме основного и подождать их завершения можно так:
if(QThreadPool::globalInstance()->activeThreadCount()) QThreadPool::globalInstance()->waitForDone();


Крутить цикл для чтения из чего? Из файла или Вы серверную\клиентскую сторону сетевого приложения пишете? Во втором случае, удобнее, как мне кажется, использовать сигнал readyRead().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 6.10.2011, 9:01
Сообщение #8


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(gpepsi @ 5.10.2011, 13:34) *
у меня куча потоков. для каждой заводить переменную ?

Зачем для каждого? Достаточно разок завести для базового, что-то вроде этого:

class MyThread : public QThread
 {
     bool m_bExit; 
 public:
     void run();
 };

 void MyThread::run()
 {
     // ...
     while( !m_bExit)
     {
        // ...
        ReadFile(...);
     }
 }

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 6.10.2011, 13:35
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 6.10.2011, 10:01) *
Зачем для каждого? Достаточно разок завести для базового, что-то вроде этого:


а как тогда с циклом обработки событий быть, если он запускается через exec, а мне нужно, чтоб поток посылал сигналы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 6.10.2011, 14:42
Сообщение #10


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Или выносить в другой поток или не использовать цикл, а пользоваться только сигналами...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 6.10.2011, 15:05
Сообщение #11


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 6.10.2011, 15:42) *
Или выносить в другой поток или не использовать цикл, а пользоваться только сигналами...


ну а если мне нужно и цикл крутить и сигналить ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 6.10.2011, 15:38
Сообщение #12


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


А ты попробуй.
Механизм сигналов и слотов асинхронный, если ты не будешь тупо всисеть в sleep в потоке, который должен получить сигнал, то значит всё долно работать.

И еще, как ты думаешь в твоём коде:
main()
{
   QCoreApplication app(...);
   MyThread th;
   ...
   app.exec();
   ...
   th.quit();
   th.wait();
   return 0;

}
дойдет выполнение до th.quit(); ?
Мне кажется, что дальше app.exec(); не пройдет. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 6.10.2011, 17:08
Сообщение #13


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 6.10.2011, 16:38) *
А ты попробуй.


а что тут пробовать
#include <QThread>

class Thread : public QThread {
    Q_OBJECT
private:
    virtual void run(void);

public :
    explicit Thread(QObject* parent) : QThread(parent) {}
    virtual ~Thread() {}

signals:
    void send(void);
};

class Owner : public QObject {
    Q_OBJECT
private:
    Thread m_thread;

    virtual void timerEvent ( QTimerEvent * event );

public :
    explicit Owner(QObject* parent = nullptr);
    virtual ~Owner() {}
    
public slots:
    void recv(void);
};


код
#include "main.h"
#include <QtCore/QCoreApplication>
#include <QDebug>

void Thread::run( void )
{
    forever
    {
        emit send();
        QThread::msleep(1000);
    }
}

Owner::Owner( QObject* parent /*= nullptr*/ ) : QObject(parent), m_thread(this)
{
    connect(&m_thread, SIGNAL(send()), this, SLOT(recv()));
    m_thread.start();

    startTimer(5000);
}

void Owner::recv( void )
{
    qDebug() << "received signal";
}

void Owner::timerEvent( QTimerEvent * event )
{
    m_thread.quit();
    m_thread.wait();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Owner owner;
    return a.exec();
}


без цикла обработки quit не прокатывает

Сообщение отредактировал gpepsi - 6.10.2011, 17:08
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 6.10.2011, 17:18
Сообщение #14


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Посмотри на: QCoreApplication::processEvents, он как раз делает то, что тебе нужно...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver47
  опции профиля:
сообщение 6.10.2011, 17:40
Сообщение #15


Активный участник
***

Группа: Участник
Сообщений: 356
Регистрация: 1.4.2010
Пользователь №: 1584

Спасибо сказали: 40 раз(а)




Репутация:   6  


Цитата
void Thread::run( void )
{
    forever
    {
        emit send();
        QThread::msleep(1000);
    }
}


Зачем это? Что Вы делаете в цикле то?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 6.10.2011, 18:45
Сообщение #16


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 6.10.2011, 18:18) *
Посмотри на: QCoreApplication::processEvents, он как раз делает то, что тебе нужно...


бесконечный цикл он все-равно не сбросит, так что без флага не обойтись :(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver47
  опции профиля:
сообщение 6.10.2011, 19:12
Сообщение #17


Активный участник
***

Группа: Участник
Сообщений: 356
Регистрация: 1.4.2010
Пользователь №: 1584

Спасибо сказали: 40 раз(а)




Репутация:   6  


Так всетаки зачем бесконечный цикл то? Мое мнение такое - если бесконечный цикл - то наследоваться от QThread нафиг не нужно - делаем обычный QtConcurrent
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 6.10.2011, 19:17
Сообщение #18


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


processEvents не сбрасывает ничего, а просто дает отработать сигналам для данного потока.
А если цикл не просто бесконечный, с условием, тогда всё в порядке.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 7.10.2011, 7:52
Сообщение #19


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 6.10.2011, 20:17) *
А если цикл не просто бесконечный, с условием, тогда всё в порядке.

то есть самому контролировать выход ?
Цитата(ViGOur @ 6.10.2011, 20:17) *
processEvents не сбрасывает ничего, а просто дает отработать сигналам для данного потока.

руками вместо exec ?

Цитата(silver47 @ 6.10.2011, 20:12) *
Так всетаки зачем бесконечный цикл то? Мое мнение такое - если бесконечный цикл - то наследоваться от QThread нафиг не нужно - делаем обычный QtConcurrent


а чем он лучше и как решит это мою проблему ?

P.S. и кстати как быть с сигналами. Если объект создан в главном потоке, то и сигналы в главном потоке будут обрабатываться, а если объект создан в run ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 7.10.2011, 8:34
Сообщение #20


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата
то есть самому контролировать выход ?
Да, именно так. у тебя же цикл не с вечным sleep'ом, вот и вызывай на каждой его итерации processEvents. А он в свою очередь будет обрабатывать сигналы и вызывать что нужно...

Цитата
руками вместо exec ?
Да. Выше уже описал...

Цитата
P.S. и кстати как быть с сигналами. Если объект создан в главном потоке, то и сигналы в главном потоке будут обрабатываться, а если объект создан в run ?
Запомни, в каком потоке создан объек, в том он и обрабатывается. Если тебя это не устраивает, то после создания объекта ты его можешь передать в другой поток с помощью: void QObject::moveToThread ( QThread * targetThread )
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gpepsi
  опции профиля:
сообщение 7.10.2011, 9:00
Сообщение #21


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 31.3.2010
Пользователь №: 1582

Спасибо сказали: 0 раз(а)




Репутация:   0  


ViGOur, а если я создаю поток только для вычитывания и разбора данных. Далее я хочу разобранные данные отдать в GUI для отрисовки.
Получается, что в run я должен это все делать, а отдавать данные через сигнал. Если объект создан в главном потоке, то и сигнал будет
обработан в главном потоке, что позволит отрисовать их в GUI.
Причем processEvents будет не нужен, т.к. QCoreApplication::exec обрабатывает свой цикл событий.
Причем в данно случае я могу объекту потоку послать сигнал, который будет обработан в главном потоке.

Я правильно размышляю ?

Единственное остался вопрос - зачем тогда вообще создавать объекты в run как в примере
 class MyThread : public QThread
 {
 public:
     void run();
 };

 void MyThread::run()
 {
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
 }

если для GUI их все-равно придется отдавать в главный поток, что за нас делает сигнал

Кстати, если я не использую потоки, а только сигналы, например, вычитывая данные из сокета вся обработка будет в главном потоке, то приведет
к подвисанию GUI если данных очень много

P.S. А чем тогда QtConcurrent полезен ?

Сообщение отредактировал gpepsi - 7.10.2011, 9:02
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 7.10.2011, 9:10
Сообщение #22


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Чтобы было меньше вопросов, предлагаю тебе почитать вот что:
1. Поддержка потоков в Qt
2. Сигналы и слоты

Там не так много букв как кажется, и как показывает практика как хотелось бы, и это базовые знания, которые нужно знать каждому, кто работает с Qt и использует потоки. Ну а без сигналов тут разумеется никуда.

И если после прочтения у тебя возникнут вопросы, то задавай их, но я думаю они сами по себе отпадут. :)

QtConcurrent, там тоде описан...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V   1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 14.7.2025, 9:02