Название: как правильно работать с QThread? (закачка файла в треде) Отправлено: Unnamed_Hero от Июль 09, 2008, 09:49 Хочу понять, как правильно работать с тредами. Почитав книги по qt4, понял мало, там очень сухо всё описано.
Хочу сделать тред, в котором будет проходить закачка файла. Соответственно, при создании в него должны передаваться параметры - откуда и куда качать файл. Значит в треде должны быть свои сигналы и слоты. В методе треда run() последней строчкой стоит exec() Если стартовать тред с помощью start(), то он запускается и сразу же помирает, не скачав и байта (тред не ловит ни слотов, ни сигналов). Если запускать с помощью run(), то тред отрабатывает, но после отработки тред виснет, т.е. программа висит в ожидании. Если в программе нажать на quit, то, видимо, тред грохается и программа продолжает работать. повторное нажатие на quit срабатывает нормально. Вероятно, я не могу выйти из EventLoop, вызов quit(), exit(0), exit() - не помогают. Ну, и главный номер программы - мой ugly code: тредовый .h Код: class get_xml : public QThread тредовый .cpp Код: get_xml::get_xml (QObject *parent,QStringList *_initList) В главном классе в .h Код: get_xml *myCurrSkill; в .cpp Код: myCurrSkill = new get_xml (this,&initList); Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: SASA от Июль 09, 2008, 10:17 Первое что бросается в глаза: для запуска надо вызывать QThread::start(). Если мы вызываем run(), никаких потоков не создаётся. Просто функция исполняется в вызывающем потоке.
О потоках неплохо написано у Бланшет. Живую ссылку на книгу можно поискать здесь: http://prog.org.ru/forum/index.php/topic,765.0.html (http://prog.org.ru/forum/index.php/topic,765.0.html) Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: Unnamed_Hero от Июль 09, 2008, 10:33 А если вызывать через start(), как я уже и писал - то не создаётся EventLoop треда, т.е. слоты и сигналы просто не обрабатываются, следовательно файл не скачивается...
Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: pastor от Июль 09, 2008, 14:45 А если вызывать через start(), как я уже и писал - то не создаётся EventLoop треда, т.е. слоты и сигналы просто не обрабатываются, следовательно файл не скачивается... Вы противоречите ассистанту и опыту людей. При возове start() вызываеться метод run() и так было и есть сейчас. Цитировать void QThread::run () [virtual protected] The starting point for the thread. After calling start(), the newly created thread calls this function. The default implementation simply calls exec(). Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: Alex03 от Июль 10, 2008, 07:52 Unnamed_Hero у Вас проблема в следующем:
QHttp http - член класса потомка от QThread, который создаётся в главном потоке приложения, соответственно http "принадлежит" главному потоку. Далее Вы его сигналы коннектите к этому потомку от QThread, который тоже в главном потоке. Соответственно вызову exec() который в run просто нечего обрабатывать, у порождённого потока нет соответствующих объектов. Т.е. если Вы перенесёте QHttp http например, на стек в run() то всё начнёт работать... НО! простой connect() между http и слотами потомка QThread будет "межпоточный", и следовательно сама обработка будет в главном потоке, что не соответствует задуманной логике. Поэтому такие connect-ы надо делать с Qt::DirectConnection. P.S. Иногда можно не мудрить с потоками а всё делать в главном потоке, для работы с сокетами и т.д. в Qt для этого всё есть. Иначе надо хорошо представлять как всё это работает, использовать механизмы межпоточной синхронизации и т.д., ибо в противном случае трудноотлавливаемые грабельки будут вылазить очень долго. Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: Unnamed_Hero от Июль 10, 2008, 09:53 спасибо за разъяснение.
В итоге сделал такую реализацию, которая даже работает: в *.h треда заменил QHttp http на QHttp *_http; В стеке run() объявил QHttp http, сделал _http = &http; и вне run () общался c http через _http-> В главном классе myCurrSkill->start();myCurrSkill->wait(); Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: Alex03 от Июль 10, 2008, 12:54 в *.h треда заменил QHttp http на QHttp *_http; Можно было и new....В стеке run() объявил QHttp http, сделал _http = &http; В главном классе myCurrSkill->start();myCurrSkill->wait(); Если wait() то какой смысл в отдельном потоке?Про коннекты то поняли? readyRead() и done() надо коннектить с Qt::DirectConnection а finita() с Qt::QueuedConnection Название: Re: как правильно работать с QThread? (закачка файла в треде) Отправлено: Unnamed_Hero от Июль 10, 2008, 15:02 wait() это пока что для отладки и тестов. и для экспериментов.
Про коннекты тоже понятно, спасибо. Так и было сделано, просто в предыдущем сообщении этого я не указал. |