Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: CuteBunny от Август 01, 2012, 11:10



Название: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 01, 2012, 11:10
Есть следующий код:

Код потока:
Код
C++ (Qt)
#ifndef AUTOTHREADOBJ_H
#define AUTOTHREADOBJ_H
 
#include <QObject>
 
class QWaitCondition;
class QMutex;
 
class AutoThreadObj : public QObject
{
Q_OBJECT
 
public:
AutoThreadObj(QObject *parent = 0);
~AutoThreadObj();
void resume();
void stop();
 
public slots:
void process();
 
private:
QWaitCondition *m_condition;
QMutex *m_mutex;
volatile bool m_stop;
 
signals:
void finished();
};
#endif // AUTOTHREADOBJ_H
 
#include "AutoThreadObj.h"
 
#include <QWaitCondition>
#include <QMutex>
 
#include <QDebug>
 
AutoThreadObj::AutoThreadObj(QObject *parent)
: QObject(parent)
, m_condition(new QWaitCondition)
, m_mutex(new QMutex)
, m_stop(false)
{
 
}
 
AutoThreadObj::~AutoThreadObj()
{
 
}
 
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
m_condition->wait(m_mutex); //wait for resume
if (m_stop) {
m_mutex->unlock();
break;
}
//do something
m_mutex->unlock();
}
 
delete m_condition;
delete m_mutex;
emit finished();
}
 
void AutoThreadObj::resume()
{
m_mutex->lock();
m_condition->wakeOne();
m_mutex->unlock();
}
 
void AutoThreadObj::stop()
{
m_mutex->lock();
m_stop = true;
m_condition->wakeOne();
m_mutex->unlock();
}
 

Код главного окна:

Код
C++ (Qt)
#ifndef QTMPWND_H
#define QTMPWND_H
 
#include <QtGui/QMainWindow>
#include "ui_qtmpwnd.h"
 
class QThread;
class AutoThreadObj;
class QCloseEvent;
 
class QTmpWnd : public QMainWindow
{
Q_OBJECT
 
public:
QTmpWnd(QWidget *parent = 0, Qt::WFlags flags = 0);
~QTmpWnd();
 
private:
Ui::QTmpWndClass ui;
 
QThread *m_autoThread;
AutoThreadObj *m_autoObj;
 
protected:
void closeEvent(QCloseEvent *e);
};
 
#endif // QTMPWND_H
 
#include "qtmpwnd.h"
 
#include <QThread>
#include <QCloseEvent>
#include "autothreadobj.h"
 
QTmpWnd::QTmpWnd(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
m_autoThread = new QThread;
m_autoObj = new AutoThreadObj;
m_autoObj->moveToThread(m_autoThread);
connect(m_autoThread, SIGNAL(started()), m_autoObj, SLOT(process()), Qt::QueuedConnection);
connect(m_autoObj, SIGNAL(finished()), m_autoThread, SLOT(quit()), Qt::QueuedConnection);
m_autoThread->start();
}
 
QTmpWnd::~QTmpWnd()
{
 
}
 
void QTmpWnd::closeEvent(QCloseEvent *e)
{
if (m_autoThread->isRunning()) {
m_autoObj->stop();
m_autoThread->quit();
m_autoThread->wait();
}
delete m_autoObj;
delete m_autoThread;
e->accept();
}
 

Если нажать ctrl+shift на главном окне, оно виснет...
Если не запускать поток, то все работает...

Что я сделал нетак?

qt.4.8.1, msvs2010, windows xp


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 01, 2012, 11:59
Проблема не в твоей программе, % 98.

Если в твоих классах нигде клавиши не перехватываются, то проблема в винде.

Выкинь проект в архиве тестовый.

PS помнится был глюк с ctrl+shift  в XP. Вместо переключения языка, оно делало окно программы занятым(неактивным вроде как, неотвечающим). В общем выкидывай проект, скорее всего у тебя что-то в системе :)


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 01, 2012, 12:07
Проект...


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 01, 2012, 12:18
Всё работает, исправно и вроде даже без утечек. Ничего странного.


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 01, 2012, 12:20
Всё работает, исправно и вроде даже без утечек. Ничего странного.

Какая версия qt и платформа у Вас?


Название: Re: ctrl+shift - вешает программу
Отправлено: Igors от Август 02, 2012, 02:29
Проверил на OSX, зависания не наблюдаю.
Код потока:
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
m_condition->wait(m_mutex); //wait for resume
if (m_stop) {
m_mutex->unlock();
break;
}
//do something
m_mutex->unlock();
}
 
delete m_condition;
delete m_mutex;
emit finished();
}
 
Формальных ошибок нет, но этот метод будет тормозить, может "не разбудиться" по resume и рухнет если его вызвать дважды. Многовато  :)


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 06:52
Пробовал на W7 sp1 x64 и WXP sp3 x86. :)


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 09:19
Подобный глюк до сих пор есть у Qt Creator. Поищи, тут на форуме обсуждался. "Срабатывал" только если на Ctrl+Shift завязано переключение раскладки. Не знаю, общая ли у этих глюков причина, но поведение очень похоже.
Проверил Win 7 x64, Qt 4.8.1, MinGW - подтверждаю наличие глюка. Зависает при переключении раскладки - у меня не Ctrl+Shift. Причем, если QtCreator "раздуплялся" через некоторое время (~20 сек), то тут полный зависон. Можно добавить информацию на баг-трекер.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 09:22
Да, кстати, IDE - Visual Studio 2008 :)


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 09:32
Нашел старые темы на эту тему :).
http://www.prog.org.ru/topic_15586_0.html
http://www.prog.org.ru/topic_12359_0.html


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 09:51
Интересно, что поток в зависшем приложении продолжает исправно выполняться. То есть виснет где-то в недрах Qt.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 10:17
Мб просто QtCreator зацикливает очередь событий гуи потока? Тем самым объясняется, почему второй поток работает безболезненно - у него другая очередь событий.
И это зависит не от системы 100% - тогда бы висли все потоки, по идее :)

У вас там в нём нет никаких хитрых настроек? типа переключать язык по ctrl+shift, независимо от системы и прочая?

PS Конечно хорошо было бы логгировать воздействия креатора на проект :) интересненько.


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 02, 2012, 10:44
Попробовал сменить сочетание клави для смены языка с ctrl+shift на alt+shift, теперь у меня виснет при alt+shift, при ctrl+shift не виснет...

Блин попробую поставить qt4.8.2 может глюк какой-нибудь в 4.8.1 под windows xp...


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 02, 2012, 10:48
Проверил на OSX, зависания не наблюдаю.
Код потока:
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
m_condition->wait(m_mutex); //wait for resume
if (m_stop) {
m_mutex->unlock();
break;
}
//do something
m_mutex->unlock();
}
 
delete m_condition;
delete m_mutex;
emit finished();
}
 
Формальных ошибок нет, но этот метод будет тормозить, может "не разбудиться" по resume и рухнет если его вызвать дважды. Многовато  :)

Буду признателен, если покажите/расскажите, как улучшить данный код...:)


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 02, 2012, 10:49
p.s.: еще забыл сказать, что qt.4.8.1 у меня была собрана из исходников, не sdk и не бинарник... может собрал/собралось криво...


Название: Re: ctrl+shift - вешает программу
Отправлено: LisandreL от Август 02, 2012, 11:11
А зависания бывают только под средой или в отдельно запускаемом exe-шнике тоже?


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 02, 2012, 11:48
А зависания бывают только под средой или в отдельно запускаемом exe-шнике тоже?

У меня в отдельном экзе тоже виснет, я запускаю debug-версию через консоль с qt-vars


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 12:24
4.8.2 не поможет. Эта хрень тянется еще 2009 года и у меня проявляется на всех Windows, всех компиляторах и всех версиях Qt. Приложенный автором темы проект виснет где-то в глубине ntdll.LdrFindResource и в debug и в release сборках, запущенный как из-под Creator, так и как отдельное приложение. При этом, повторюсь, сам код из void AutoThreadObj::process() продолжает прекрасно выполняться и в зависшем приложении.


Название: Re: ctrl+shift - вешает программу
Отправлено: Igors от Август 02, 2012, 12:38
Проверил на OSX, зависания не наблюдаю.
Код потока:
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
m_condition->wait(m_mutex); //wait for resume
if (m_stop) {
m_mutex->unlock();
break;
}
//do something
m_mutex->unlock();
}
 
delete m_condition;
delete m_mutex;
emit finished();
}
 
Формальных ошибок нет, но этот метод будет тормозить, может "не разбудиться" по resume и рухнет если его вызвать дважды. Многовато  :)

Буду признателен, если покажите/расскажите, как улучшить данный код...:)
1) Если создаете m_condition; и m_mutex в конструкторе, то и удаляйте в деструкторе. А так просто остаетесь с невалидным объектом после вызова process, а если он не будет вызван - утечка

2) все тело dо_something защищено мутексом. Значит др нитка желающая сделать resume будет ждать на мутексе пока все не закончится. Правильно делать под мутексом лишь минимальные действия (напр извлечь элемент из контейнера), освободить мутекс как можно быстрее, а там уже заниматься с данными

3) waitCondition - та же ошибка что и в букваре.
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
               m_condition->wait(m_mutex); //wait for resume
 
Нитка пытается захватить лок, но в это время др нитка (может главная) ее опередила делая resume. Что происходит дальше. Захватив лок, главная нитка делает wakeOne - но на m_condition никто еще не ждет,  wakeOne возвращает управление ничего не сделав и освобождает мутекс. Теперь AutoThreadObj получает лок и ждет, но поезд-то уже ушел. Возможно поэтому Вы поставили в исходниках wait на полсекунды  :)

Я бы посоветовал в данном случае использовать QSemapohre вместо waitCondition


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 12:46
Конечно мб это жуткий глюк у вас, но если б приложение ёкалось в ntdll, то вырубало бы полностью.

Попробуйте собрать под Visual studio.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 13:10
Конечно мб это жуткий глюк у вас, но если б приложение ёкалось в ntdll, то вырубало бы полностью.

Попробуйте собрать под Visual studio.
Bepec, когда же уже читать научимся? Повторюсь:
1. Оно не падает, оно виснет. И виснет внутри ntdll.
2. У меня проявляется на всех Windows, всех компиляторах и всех версиях Qt.

Всех компиляторах - значит Visual Studio 2008 тоже проверялся. Там виснет в ntdll.RtlUniform.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 13:37
У меня не виснет, не чешется, не грузит, не балахтается.

ЧЯДНТ?

PS тестовый проект собирал VS2008 с интеграцией. Ну почему у меня всё бачит??


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 14:05
Дак откуда ж мне знать, почему? Знал бы - сюда и не писал ничего - у себя исправил бы и дело с концом.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 02, 2012, 14:20
Соберите тогда проект и с дллками залейте. Вдруг загнётся и у меня?


Название: Re: ctrl+shift - вешает программу
Отправлено: CuteBunny от Август 02, 2012, 15:25
Проверил на OSX, зависания не наблюдаю.
Код потока:
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
m_condition->wait(m_mutex); //wait for resume
if (m_stop) {
m_mutex->unlock();
break;
}
//do something
m_mutex->unlock();
}
 
delete m_condition;
delete m_mutex;
emit finished();
}
 
Формальных ошибок нет, но этот метод будет тормозить, может "не разбудиться" по resume и рухнет если его вызвать дважды. Многовато  :)

Буду признателен, если покажите/расскажите, как улучшить данный код...:)
1) Если создаете m_condition; и m_mutex в конструкторе, то и удаляйте в деструкторе. А так просто остаетесь с невалидным объектом после вызова process, а если он не будет вызван - утечка

2) все тело dо_something защищено мутексом. Значит др нитка желающая сделать resume будет ждать на мутексе пока все не закончится. Правильно делать под мутексом лишь минимальные действия (напр извлечь элемент из контейнера), освободить мутекс как можно быстрее, а там уже заниматься с данными

3) waitCondition - та же ошибка что и в букваре.
Код
C++ (Qt)
void AutoThreadObj::process()
{
forever {
m_mutex->lock();
               m_condition->wait(m_mutex); //wait for resume
 
Нитка пытается захватить лок, но в это время др нитка (может главная) ее опередила делая resume. Что происходит дальше. Захватив лок, главная нитка делает wakeOne - но на m_condition никто еще не ждет,  wakeOne возвращает управление ничего не сделав и освобождает мутекс. Теперь AutoThreadObj получает лок и ждет, но поезд-то уже ушел. Возможно поэтому Вы поставили в исходниках wait на полсекунды  :)

Я бы посоветовал в данном случае использовать QSemapohre вместо waitCondition

Спасибо, попробую через QSemaphore.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 02, 2012, 16:47
Соберите тогда проект и с дллками залейте. Вдруг загнётся и у меня?
Ok. Вот. Qt 4.8.2, MSVS 2010 (2008 на этой машине нет). Виснет.
http://files.mail.ru/WBSEX6
От Вас тогда жду скомпилённое у Вас.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 03, 2012, 07:18
https://dl.dropbox.com/u/62712483/Release.zip
Qt 4.7.2 MSVS 2008. Библиотечки ещё сжаты upx :) Ну и дизайн чуть улучшил, а то статика напрягала.

PS Ваша версия работает как отбойный молоток - неостанавливаясь.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 03, 2012, 08:23
Ответный комплимент - Ваша так же намертво виснет, как и моя. :)
Дело всё-таки в ОС. Проверял на двух компах с Win7 х64. Пошел WinXP искать.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 03, 2012, 08:26
Проверил на корпоративной WinXP Pro SP3. Висим.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 03, 2012, 08:29
Нашёл! Punto Switcher косячит! Убираю его - и всё нормально. Кому бы теперь написать - в Nokia или в Yandex?
P.S. Давно его (Punto) подозревал, но народ писал, что в Qt Creator bug проявлялся независимо от наличия switcher.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 03, 2012, 08:43
А вы мне версию PuntoSwitcher скиньте - я тоже посмотрю.

Хех... Вполне может быть интересный глюк, что он пытается слямзить нажатые клавишы, но его игнорят :D

PS скиньте скиньте, заодно с его хуками поковыряюсь :D


Название: Re: ctrl+shift - вешает программу
Отправлено: Serr500 от Август 03, 2012, 10:26
Windows 7 SP1 32-bit, Punto Switcher 3.2.7. Переключение по Ctrl+Shift. Ничего не виснет.


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 03, 2012, 10:33
Тут возможно проблема в хуках/драйверках :) Надо бы получить нерабочую конфигурацию и покопаться.


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 03, 2012, 10:35
Punto Switcher 3.2.6
Залил сюда: http://files.mail.ru/H6P91L
Виснет даже если переключать раскладку мышью в самом Punto.
Сейчас попробую 3.2.7


Название: Re: ctrl+shift - вешает программу
Отправлено: xokc от Август 03, 2012, 10:40
Проверил с "кошерным" 3.2.7 - виснет


Название: Re: ctrl+shift - вешает программу
Отправлено: Bepec от Август 03, 2012, 10:43
*безнадёжным голосом* А можно без mail?
 А то у меня от его спутника волосы дыбом становятся. Уже задумываюсь утилитку антиспутник/гуард мейл сделать, ибо заканали :D

PS Ура повисло, но от сочетания alt+shift на 8-10 раз :)

Update: виснет при попытке изменить данные(автопереключения, сниппеты, исправление синтаксических ошибок) :D

Update2: Виснет при получении окном мессаги WM_INPUTLANGCHANGEREQUEST. Очень интересно :D Но счас обед, потом продолжу.


Название: Re: ctrl+shift - вешает программу
Отправлено: kambala от Август 03, 2012, 11:12
никаких проблем в креаторе с пунто не замечал ни под виндой (контрол+шифт) ни в мак ос (комманд+пробел) даже когда креатор не был внесен в исключения


Название: Re: ctrl+shift - вешает программу
Отправлено: Serr500 от Август 03, 2012, 11:19
У меня были проблемы в QtCreator с Punto. Автопереключение у меня выключено, если я что-то набираю не на той раскладке, то жму Break и Punto меняет раскладку. Так вот, иногда при этой операции Creator зависает и перестаёт на что-либо реагировать. Но примерно через полминуты "отвисает" и работает нормально. Свинство сие проявлялось у меня на всех версиях Creator'а, что я использовал и всех версиях Punto. От разрядности ОС это тоже не зависит - наблюдал как на 32, так и на 64-битных Windows 7.