LINUX.ORG.RU

Qt: QThread ?


0

0

Наверное туплю, но структура такая:

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

   MyBase MyBase1;

return a.exec();
}

class MyThread:public QThread{
public:

void run(){cout << «HELLO !!!!» << endl;}
}

MyBase1::MyBase1() {
MyThread mt;
............
mt.start();
............
}

Т.е. в конструкторе основного класса запускаю поток. Думаю, это как-то не
правильно, но приложение консольное, где еще запускать ?
Да, ну и поток не запускается почему-то ?



У вас есть шанс перепостить тему пока ещё никто не ответил. На будущее, пользуйтесь пожалуйста кнопкой «Предпросмотр».

Dendy ★★★★★ ()
MyBase1::MyBase1() {
    MyThread mt;
    // ............
    mt.start();
    // ............
}

И что станет с переменной mt после выхода из конструктора?

rival ★★ ()
Ответ на: комментарий от rival

> И что станет с переменной mt после выхода из конструктора?

Эт понятно, но я в качестве теста хочу хоть что-то вывести. Например,

mt.start();
sleep(5);

Должно ж HELLO вывести ?

drZlo ()
Ответ на: комментарий от drZlo

Вот что должно вывести:

$ ./qthreadexample 
QThread: Destroyed while thread is still running
Segmentation fault

А вот рабочий пример:

#include <QCoreApplication>
#include <QThread>
#include <iostream>

class MyThread : public QThread {
   public:
   void run(){ std::cout << "HELLO !!!!" << std::endl; }
};

class MyBase1 {
   MyThread mt;

public:
   MyBase1() {
       mt.start();
   }
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    MyBase1 mybase;

    return a.exec();
}

Из доков:

Note that deleting a QThread object will not stop the execution of the thread it represents. Deleting a running QThread (i.e. isFinished() returns false) will probably result in a program crash. You can wait() on a thread to make sure that it has finished.

rival ★★ ()
Ответ на: комментарий от drZlo

Даже, если так:


class MyBase1 {
  public:
    MyThread *mt;
}

MyBase1::MyBase1() {

   mt = new MyThread();
   ............
   mt->start();
   ............
}

Все равно поток не стартует...

drZlo ()
Ответ на: комментарий от drZlo

Хм… Всё работает:

#include <Qt>
#include <QCoreApplication>
#include <QThread>
#include <iostream>

class MyThread : public QThread {
public:
	void run(void)
	{
		std::cout << "Hi there!" << std::endl;
	}
};

class MyBase1 {
public:
	MyBase1(void)
	{
		mt = new MyThread();
		mt->start();
	}

	~MyBase1(void)
	{
		mt->wait();
		delete mt;
	}

private:
	MyThread* mt;

};

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	MyBase1 mybase;

	return a.exec();
}
sjinks ★★★ ()
Ответ на: комментарий от sjinks

А у тебя случаем основной процесс не завершается раньше потока?

есть такая функция в pthread.h, называется pthread_join. Может в Qt есть аналог?

Qt thread не использовал =\

desruptor ()
Ответ на: комментарий от sjinks
~MyBase1(void) 
      { 
       mt->wait(); 
       delete mt; 
      } 

Да, собственно судя по всему wait в деструкторе тебе и не хватает.

desruptor ()
Ответ на: комментарий от desruptor

Нет, основной процесс ждет в app.exec().

QThread::wait() будет аналогом pthread_join().

Кстати, без QThread::wait() тоже работает, так как поток быстро завершается, но я предпочитаю безопасный код :-)

sjinks ★★★ ()
Ответ на: комментарий от LamerOk

Деструктурирвоание объекта достаточно специфичная операция. Считаю неуместным выполнения wait в деструкторе, ибо он может быть вызван в самый неожиданный момент

namezys ★★★★ ()
Ответ на: комментарий от namezys

> ов деструкторе, ибо он может быть вызван в самый неожиданный момент

Щито?!?

А ну ка пруф-оф-концепт кода, где деструктор будет вызыван ВНЕЗАПНО, в студию.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

любое исключение сверху - неожиданый вызов деструктора

namezys ★★★★ ()
Ответ на: комментарий от namezys

1. С какого «верху»?

2. Давно ли исключения стали выбрасываться ВНЕЗАПНО?

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> Давно ли исключения стали выбрасываться ВНЕЗАПНО?

С момента появления overcommit memory allocation? :-)

Nastishka ★★★★ ()
Ответ на: комментарий от Nastishka

Айлолд.

Так чего именно - overcommit memory или memory allocation? Это как бе две разные, почти не связанные друг с другом вещи. ))

ЗЫ. Пальцем в небо. )))

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> С какого «верху»?

стека

Давно ли исключения стали выбрасываться ВНЕЗАПНО?

Всегда

namezys ★★★★ ()
Ответ на: комментарий от LamerOk

>> Всегда

Сочувствую.

везде, где нет try/catch исключение будет неожидано

namezys ★★★★ ()
Ответ на: комментарий от namezys

Именно по этому, везде, где нет try/catch их не используют.

К.О.

LamerOk ★★★★★ ()
Ответ на: комментарий от namezys

>Деструктурирвоание объекта достаточно специфичная операция. Считаю неуместным выполнения wait в деструкторе, ибо он может быть вызван в самый неожиданный момент

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

Devix ()
Ответ на: комментарий от LamerOk

> Именно по этому, везде, где нет try/catch их не используют.

да ладно. в моем коде try/catch встречается внизу цикла обработки сообщений и где нить по середине.

И пишу код так, что любое действие может бросить исключение и все раскрутиться до обработки сообщений. Причем мягко, и ничего не сломается.

Именно это я и имею в виду, говоря что они неожиданны. Я же не знаю, что сосед Вася написал в функции сделайЧтоТоЧтоНадо

namezys ★★★★ ()
Ответ на: комментарий от Devix

Вопрос сложный. Он имхо того же типа, что и бросание исключений в деструкторе.

Ожидание - это скорее операция завершения, чем деструкурирование. А если кто нить в этот момент попросит из того потока при завершении основной поток? замкнутый цикл.

namezys ★★★★ ()
Ответ на: комментарий от namezys

> любое действие может бросить исключение и все раскрутиться до обработки сообщений. Причем мягко, и ничего не сломается.

Тогда в чем проблема с wait'ом в деструкторе? О_о

LamerOk ★★★★★ ()
Ответ на: комментарий от Nastishka

> overcommit это

Деточка, мы тут об исключениях разговариваем.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> Тогда в чем проблема с wait'ом в деструкторе? О_о

фактически wait должен дождаться завершения потока. А потом может и зависить от обработки сообщений основного потока. Тогда все -fail

namezys ★★★★ ()
Ответ на: комментарий от namezys

> Ожидание - это скорее операция завершения, чем деструкурирование.

Что мешает одному быть частью другого?

А если кто нить в этот момент попросит из того потока при завершении основной поток?


Думать надо, когда исключения бросаешь. ))

LamerOk ★★★★★ ()
Ответ на: комментарий от namezys

> А потом может и зависить от обработки сообщений основного потока.

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

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> Думать надо, когда исключения бросаешь. ))

А вот как раз не надо. Исключение надо бросать всегда при ошибке

namezys ★★★★ ()
Ответ на: комментарий от LamerOk

> Ну так это проблемы дизайна приложения, не проблемы ожидания потока в деструкторе.

Я считаю что это тоже проблема дизайна. А вот ожидание другого часто не проблема дизайна.

Проблема в том, что исключение будет брошено из другого кода, а не из кода объекта потока

namezys ★★★★ ()
Ответ на: комментарий от namezys

> Исключение надо бросать всегда при ошибке

Если есть гарантия, что его перехватят в корректной точке, иначе - упс.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> Если есть гарантия, что его перехватят в корректной точке, иначе - упс.

Проглатить ошибку себе дороже

namezys ★★★★ ()
Ответ на: комментарий от namezys

> Проблема в том, что исключение будет брошено из другого кода, а не из кода объекта потока

Здесь нет никакой проблемы, если точно известно, что поток завершится. Ну и до кучи хинт: послать сигнал завершения потока можно всё в том же деструкторе, строчкой выше. ;)

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

Вообще тут вопрос архитектура.

По мне на стеке должен быть объект, которые вызовет завершение потока, а потом сконфигурирует состояние своего потока так, чтоб он работал, как ожидается другим кодом (а не ждал), но при этом учитывал бы, что тот поток завершается

namezys ★★★★ ()
Ответ на: комментарий от namezys

> Вообще тут вопрос архитектура.

Именно.

чтоб он работал, как ожидается другим кодом (а не ждал),


В половине случаев «работа» потока - это ждать.

но при этом учитывал бы, что тот поток завершается


А если без того потока его работа вообще не имеет смысла? Так что вот.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

Спор не имеет смысла без конкретного примера. Но я предпочитаю при деструктурировании ничего не делать, кроме как возвращать в состояния (условно говоря) до конструирования

namezys ★★★★ ()
Ответ на: комментарий от namezys

> Спор не имеет смысла без конкретного примера.

Да, так же как и утверждение:

wait в деструкторе? это ужасно


;)

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

>Что мешает одному быть частью другого?
знаешь такое слово: говнокод?
Деструктор - это всегда освобождение занятых ресурсов, а не ожидание, когда они сами освободятся.

xydo ★★ ()
Ответ на: комментарий от xydo

Читай дальше. И вообще, возьми за привычку читать до конца, а потом уже постить.

LamerOk ★★★★★ ()
Ответ на: комментарий от xydo

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

xydo ★★ ()
Ответ на: комментарий от LamerOk

>И вообще, возьми за привычку читать до конца, а потом уже постить.
возьми привычку не нести чушь не подумав!
и, да, запихни свои советы куда подальше!!

xydo ★★ ()
Ответ на: комментарий от xydo

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

возьми привычку не нести чушь не подумав!

LamerOk ★★★★★ ()
Ответ на: комментарий от namezys

> любое исключение сверху - неожиданый вызов деструктора

Исключение не должно быть неожиданным. За неожиданные исключения нужно руки отрывать.

sjinks ★★★ ()
Ответ на: комментарий от namezys

> как возвращать в состояния (условно говоря) до конструирования

А там что делается? Только есть нюанс, что при удалении живого потока можно получить segfault. Поэтому если сегфолты не нужны, лучше подожать завершения потока.

sjinks ★★★ ()
Ответ на: комментарий от sjinks

> Исключение не должно быть неожиданным. За неожиданные исключения нужно руки отрывать.

Да. Тогда ты должен знать ВЕСЬ код

namezys ★★★★ ()
Ответ на: комментарий от LamerOk

Дяденька, вы сделайте malloc 16 гигабайт с включенным overcommit, забейте эту память нолями, а потом «разговаривайте об исключениях». Может после этого вы поймете, что исключение действительно может произойти в любой момент времени :-)

Nastishka ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.