Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Гурман от Ноябрь 13, 2014, 00:24



Название: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 00:24
Столкнулся со странным поведением при отладке трех взаимодействующих процессов. Бутерброд толстый, весь код нереально показать, проще в общем описать.

1я нить выполняется циклически и пихает в сигнал разнообразные данные, упакованные в QVariant - пока проверяю со строками, целыми и вещественными числами. Сигнал по определению Queued. Эта нить находится в отдельной загружаемой DLL.
В другой загружаемой DLL в пространстве "основного" процесса приложения находится приемник сигнала, который получает данные, распознает их тип, и запускает на выполнение 3ю нить, обрабатывающую по-разному данные разного типа. Причем запускает он её не простым стартом QThread, а снятием ранее запущенной нити, которая к этому времени находится в WaitCondition. То есть, основной процесс-приемник сигнала делает wakeOne() для ожидающей нити, после того, как разобрал данные и подготовил для обработки. И сразу, как только он разбудил обработчик, основной процесс приостанавливается на своём WaitCondition (иначе он начинает ловить следующие входящие сигналы, и начинается чехарда при подготовке данных, которые никто не успевает обработать). Когда обработка закончена, 3я нить снимает основной процесс с ожидания вызовом wakeOne() сама снова становится в WaitCondition, и приём повторяется.

Это всё очень славно работает, пока... не пошевелишь мышкой. Стоит это сделать - не понятно по какой причине интерфейс замерзает, но не полностью. Приложение реагирует на кнопку закрытия, причем не тупо закрывается, а нормально отрабатывает все заложенные функции (а там производится рассылка команды "умри" нескольким плагинам, которые еще и отвечают потом, что они умерли, и только после этого приложение закрывается - это всё выполняется). Более того, судя по потреблению процессора и посвистыванию дросселей материнки, 1я нить, которая отправляет данные, продолжает работать - очередь наполняется, свободная память при этом потихоньку исчезает. Ощущение такое, будто обрабатывающая нить ушла в WaitCondition, а основной процесс её почему-то оттуда не снимает. Совершенно точно нет состояния dead-lock - в нём приложение у меня нормально не закрывается, это проверенно. И при dead-lock в отладчике появляется соответствующее сообщение - тут его нет.

Причем всё это на не самом слабеньком процессоре с 4-мя ядрами...

Вот вопрос - кто-нибудь сталкивался с чем-то подобным? Когда отработка интерфейса "сбивает" работу слотов, в которых используются функции синхронизации с помощью WaitCondition? Я делал такие синхронизации несколько раз, но ни разу именно так, и ни разу не влипал в подобное. Буду, конечно, пытаться изменить логику, но интересно - может есть какие-то известные ограничения?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 13, 2014, 09:30
В UI'ном трэде что-то делается?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 10:45
в UI (я его назвал основным процессом) слот принимает сигнал, определяет тип, декодирует данные, кладет их на специальный стек (всё это очень быстро, сотня строк без тяжелых вызовов), будит нитку обработчика и становится в ожидание следующего сигнала - наверно, в последнем проблема, но странно, что пока мышкой не повозишь, всё нормально


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 13, 2014, 10:54
в UI (я его назвал основным процессом) слот принимает сигнал, определяет тип, декодирует данные, кладет их на специальный стек (всё это очень быстро, сотня строк без тяжелых вызовов), будит нитку обработчика и становится в ожидание следующего сигнала - наверно, в последнем проблема, но странно, что пока мышкой не повозишь, всё нормально

ну вот в этом то и проблема. выноси этот функционал за пределы UI'ного треда, а основной поток используй только для обновления интерфейса (отображения данных) и взаимодействия с пользователем.

даже если нет тяжелых вызовов, все равно есть ожидание. в этом и проблема. ожидание нельзя делать в UI'ном треде, т.к. помимо твоего кода там происходит много чего связанного с интерфейсом. Постоянные ивенты, перерисовки, апдейты и прочее прочее...


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 13, 2014, 10:57
Скорее всего у вас глушится UI поток сигналами.
Интерфейс замерзает - непонятное у вас описание.
То ли интерфейс у программы замерзает - она не реагирует на наведение/щелчки мышкой и прочее.
То ли у вас окно зависает - покрывается блюром и считается зависшим системой.

Но, думаю, что у вас просто где-то ошибка и/или всё же упущение количества вызовов.
Вот такие расплывчатые догадки в ответ на общее описание.

PS ++ к предыдущему оратору


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 11:12
Интерфейс замерзает - непонятное у вас описание.
То ли интерфейс у программы замерзает - она не реагирует на наведение/щелчки мышкой и прочее.
То ли у вас окно зависает - покрывается блюром и считается зависшим системой.

интерфейс не реагирует на нажатия и наведение, кроме кнопки закрытия окна (на неё реагирует), перерисовывается нормально

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

значит придется еще одну нить запускать, для приёма и декодирования сигналов - в нити обработчика это делать сложно, она физически в другой DLL находится, отлаженной, и написанной преимущественно на Си


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 11:39
Да, проблема в ожидании в основном процессе. Убрал его и сделал передающий сигнал Blocking, интерфейс стал нормально работать.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 19:57
А шайтан... Если в QThread запустилась нитка, залочила некий мутекс, завершилась (но мутекс не разлочился), и потом снова запустилась (тот же объект QThread) - при повторном запуске, вместо dead-lock она в этом мутексе просто молча залипает. Объект тот же, но нитка другая, другой ThreadID. И разлочить после перезапуска этот мутекс не нельзя - слетает с ошибкой.

Что-то я не помню предупреждения об этом в документации, а просто так это не совсем очевидно.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 13, 2014, 20:22
QMutexLocker используйте.

И насколько я помню, повторные локи всегда такое вызывали :D Там где то строчка имеется что всегда нужно контролить мутекс, иначе будет ой ой ой.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 21:11
QMutexLocker используйте.

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

И насколько я помню, повторные локи всегда такое вызывали :D Там где то строчка имеется что всегда нужно контролить мутекс, иначе будет ой ой ой.

само собой, но речь не об этом, а о том, что при разных последовательных запусках одного и того же QThread::run() получаются разные нити, которые не могут работать с одним и тем же мутексом, также как если бы это была одна и та же нить - а проблема у меня именно в этом


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 13, 2014, 23:01
Локер поможет в том, что при завершении run автоматом разлочит мутекс. Он берёт контроль за его состоянием на себя ) и ваша проблема исчезает :)

PS это кстати поведение совершенно нормально. мой первый проект с потоками получал данные из контейнера давно удалённой нити :)


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 23:32
Локер поможет в том, что при завершении run автоматом разлочит мутекс. Он берёт контроль за его состоянием на себя ) и ваша проблема исчезает :)

В руководстве нет ничего про разлочивание мутекса локером при завершении run(). Там вообще не описано никакой связи между QThread и МутексЛокером.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 13, 2014, 23:42
QMutexLocker блочит мутекс в своем конструкторе и разлочивает в деструкторе. Потому создавая в начале run QMutexLocker вы получаете гарантию, что в конце у вас будет разлоченный мутекс :)


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 13, 2014, 23:53
QMutexLocker блочит мутекс в своем конструкторе и разлочивает в деструкторе. Потому создавая в начале run QMutexLocker вы получаете гарантию, что в конце у вас будет разлоченный мутекс :)

Нет такой возможности. QThread::run() и мутекс находятся в разных DLL с ручной загрузкой, то есть, в плагинах. Более того, выполняемый в run() код находится в третьем плагине. Любой из плагинов может отсутствовать. Код, где мутекс и синхронизируемый код умеют общаться, но приплетать туда еще и run() будет идеологически неверно. Этот run ничего не знает и не иммет права знать о загруженных плагинах, и вообще выглядит вот так

Код:
void RunThread::run()
{
    _main( argc, argv );
}

То есть, в той же нити, где мутекс лочится, негде разместить разлочивание, я над этим уже несколько часов голову ломаю. Я так понимаю, МутексЛокер не сработает, если его создать в одной нити, а удалить из другой? Собственно, должен случиться тот же ассерт, что и про попытке просто сделать лок и анлок мутекса в разных нитях.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 09:26
Я так понимаю, МутексЛокер не сработает, если его создать в одной нити, а удалить из другой? Собственно, должен случиться тот же ассерт, что и про попытке просто сделать лок и анлок мутекса в разных нитях.

Мьютекс локер это критическая секция.
Работает в рамках внутри { }.

Это тот же

{
mutex.lock();
// do something
mutex.unlock();
}

Только немного удобнее, особенно если всякие if else с return'ами.

Лок анлок мьютекса в разных потоках делать не просто можно, а нужно.


Цитировать
не вполне понятно, чем он поможет, у меня нет необходимости синхронизировать мутекс с созданием и удалением чего либо, поскольку ничего не создается и не удаляется

мьютекс не только для синхронизации создания и удаления.
мьютекс для синхронизации по разделяемому ресурсу. при этом ресурс может на самом деле быть вообще статичным, т.е. не меняться.

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

можно комбинировать 2 и более мьютексов, тогда в каких то случаях потоки смогут работать парраллельно. в общем из мьютекса можно сообразить много всяких интересных штук.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 09:32
Цитировать
само собой, но речь не об этом, а о том, что при разных последовательных запусках одного и того же QThread::run() получаются разные нити, которые не могут работать с одним и тем же мутексом, также как если бы это была одна и та же нить - а проблема у меня именно в этом

Что за последовательные запуски одного и того же QThread::run? Это как?
Ты создаешь разные объекты QThread и делаешь им start()?

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

Зачем последовательно запускаешься QThread::run?

Может лучше сделать?

Код:
run() {
    while(running) {
        // do stuff or just wait for signal
        exec();
    }
}


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 12:31
Что за последовательные запуски одного и того же QThread::run? Это как?
Ты создаешь разные объекты QThread и делаешь им start()?

нет, разумеется... во-первых, не start(), а run(), во-вторых один объект QThread один раз создан, когда надо он запускается, выполняет действия, останавливается, потом когда снова надо снова запускается и т.д. - такова логика задачи, и это изменить нельзя

за все остальные банальности спасибо, но всё это мне давным давно известно, и ничего для решения проблемы не даёт


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 12:57
Что за последовательные запуски одного и того же QThread::run? Это как?
Ты создаешь разные объекты QThread и делаешь им start()?

нет, разумеется... во-первых, не start(), а run(), во-вторых один объект QThread один раз создан, когда надо он запускается, выполняет действия, останавливается, потом когда снова надо снова запускается и т.д. - такова логика задачи, и это изменить нельзя

за все остальные банальности спасибо, но всё это мне давным давно известно, и ничего для решения проблемы не даёт

если ты дергаешь run(), то он выполняется в том же потоке.
а если start(), то он создает поток и в нем выполняет run().

логика абсолютно нормальная. криво реализовано просто.

если все известно, не вижу причин чтобы приложение не работало.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 13:25
если все известно, не вижу причин чтобы приложение не работало.

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

проблема в том, что разные участники процесса находятся в разных плагинах, взаимодействие между которыми не так легко осуществлять - обмен обычными данными нормально по сигнал-слотам производится, но вот управление потоками уже не так просто


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 14:49
если все известно, не вижу причин чтобы приложение не работало.

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

проблема в том, что разные участники процесса находятся в разных плагинах, взаимодействие между которыми не так легко осуществлять - обмен обычными данными нормально по сигнал-слотам производится, но вот управление потоками уже не так просто

если делаешь stop start, то это нормально.
а вообще не очень понимаю что значит последовательный запуск одного и того же qthread... несколько раз дергаешь start?


советую вот такое попробовать:

Код:
void MyThread::run() {
    // init
    mContinue = new QMutex;
    mWaitCondition = new QWaitCondition;

    while(running) {
        lock();
        // do stuff
        unlock();

        if (pause) {
            mWaitCondition->wait(mContinue);
        }

        exec();
    }
}

void MyThread::pause() { pause = true; }

void MyThread::resume() {
    if (pause) {
        pause = false;
        mWaitCondition->wakeAll();
    }
}

Так сам сможешь контролировать когда приостановить поток, когда продолжить работу. Причем без сигналов, соотв. быстрее.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 15:30
Код:
[quote author=vulko link=topic=27922.msg203570#msg203570 date=1415965762]
а вообще не очень понимаю что значит последовательный запуск одного и того же qthread... несколько раз дергаешь start?

Типа того, только не я дергаю - пользователь. Объект QThread создается один раз при старте задачи и связывается с загруженными плагинами. Создавать его каждый раз заново нельзя - это поломает всю структуру и весь отлаженный код, которого море. Когда пользователю надо, он нажимает кнопочку и выполняется соответствующий QThread::start(). Более того, таких нитей может и должно быть несколько, причем пользователь может запускать их произвольно. И они общаются друг с другом через сигнал-слоты, которые пользователь может связывать вручную. По другому никак нельзя. Таково условие задачи ака ТЗ.

советую вот такое попробовать:

Код:
void MyThread::run() {
    // init
    mContinue = new QMutex;

Это невозможно. MyThread не имеет права ничего знать про мутексы где-то там внутри. Он лишь выполняет код загруженного плагина. Плагин может иметь мутексы, может не иметь.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 18:12
Это невозможно. MyThread не имеет права ничего знать про мутексы где-то там внутри. Он лишь выполняет код загруженного плагина. Плагин может иметь мутексы, может не иметь.

омг...
в каком нутри?

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

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


Типа того, только не я дергаю - пользователь. Объект QThread создается один раз при старте задачи и связывается с загруженными плагинами. Создавать его каждый раз заново нельзя - это поломает всю структуру и весь отлаженный код, которого море. Когда пользователю надо, он нажимает кнопочку и выполняется соответствующий QThread::start(). Более того, таких нитей может и должно быть несколько, причем пользователь может запускать их произвольно. И они общаются друг с другом через сигнал-слоты, которые пользователь может связывать вручную. По другому никак нельзя. Таково условие задачи ака ТЗ.

вернемся к началу.
плагины-шмагины. все это никакого отношения не имеет к вопросу. более того, если как ты говорил, плагина может не быть, то вообще ничего делать в run() не надо. т.е. неплохо бы проверить если он вообще для начала.

а вопрос твой изначально был таким:
Код:
Если в QThread запустилась нитка, залочила некий мутекс, завершилась (но мутекс не разлочился), и потом снова запустилась (тот же объект QThread) - при повторном запуске, вместо dead-lock она в этом мутексе просто молча залипает.

если поток завершил работу, но не разлочил мьютекс, значит это кривой поток. или кривой программист.
для таких случаев есть крит секция. вот её и используй!

молча залипает, потому что, как уже говорили тебе выше, мьютекс лочится дважды из одного и того же потока. т.е. лочится сам на себе. это почти dead lock, только в рамках одного потока, а не взаимная блокировка потоков.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 14, 2014, 19:49
Тут явная хрень в архитектуре.
Нитка блочащая мутекс не создаёт мутекс. Мутекс имеется в dll, а может и не иметься. Это сюрреалистический бред архитектуры.

Соберитесь. Разложите задачу на составные части. И не позволяйте сущностям убегать из своей части. Нитка лочащая  мутекс должна его разлочивать Точка


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 20:37
Тут явная хрень в архитектуре.
Нитка блочащая мутекс не создаёт мутекс. Мутекс имеется в dll, а может и не иметься. Это сюрреалистический бред архитектуры.

Соберитесь. Разложите задачу на составные части. И не позволяйте сущностям убегать из своей части. Нитка лочащая  мутекс должна его разлочивать Точка

Я НЕ ПОЗВОЛЯЮ УБЕГАТЬ СУЩНОСТЯМ! Мутекс может иметься в DLL, а может и не иметься. И в одной задаче могут быть плагины как с мутексами, так и без мутексов. И даже плагин могу не я написать, а кто-то другой лет через пять. То есть, лочиться и разлочиться мутекс должен только внутри плагина, и больше нигде. Никакого бреда тут нет.

Сюрреализм есть, но он в том, что один QThread при разных запусках имеет разный ThreadID. Это потому, что start() запускает каждый раз новую нить на системном уровне. Я бы сделал так, чтобы в конструкторе самого QThread создавалась и запускалась на время существования этого объекта только одна нить, но чтобы в самом конструкторе она ставилась в ожидание, а start() просто разрешал ей работать, вызывая run(). Тогда у всех последовательных запусков был бы один тот же ThreadID, и мутексы, залоченные при одном запуске, можно было бы разлочить при следующем запуске. То есть - один QThread == один и тот же процесс. Всегда, пока этот QThread существует. Увы, но в Qt это совсем не так. Это и есть сюрреализм.

С утра, проспавшись, вдруг подумал, а почему не сделать так в процедуре, которая ожидает прихода сигналов (сигналы принимаются основным потоком, как написано в начале):

Код:
        _waiterLockMutex();         //     waiterMutex.lock();
        _waiterLocker();            //     waiterWaitCondition.wait( &waiterMutex );
        _waiterUnLockMutex();       //     waiterMutex.unlock();

в приемнике сигнала просто
Код:
        waiterWaitCondition.wakeOne();

Сделал. Вроде работает всё...


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 20:43
О чем вообще речь? Вы хоть знаете что такое мьютекс и как он работает?
Вы знаете что залочив разные мьютексы из одного потока ничего не случиться?

Причем тут вообще внутренности плагина и его мьютексы? Это все остается внутри!


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 20:54
Вы хоть знаете что такое мьютекс и как он работает?

знаю, где-то с начала 90-х... в конце 90-х в реализации семафоров BeOS ошибку нашел

у меня проблема была не в мутексах, читайте внимательнее


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 21:34
Вы хоть знаете что такое мьютекс и как он работает?

знаю, где-то с начала 90-х... в конце 90-х в реализации семафоров BeOS ошибку нашел

у меня проблема была не в мутексах, читайте внимательнее


может стоит изъясняться понятным образом?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 22:04
может стоит изъясняться понятным образом?

у понятности изложения всегда есть две стороны...


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 14, 2014, 22:12
Я тоже не могу уловить ваши рассуждения. У вас проблема с Mutex. Выше вы говорили что лочится он в потоке, А разлочивается хз где. И дальше говорите что его вообще может не быть.

Как может существовать поток с мутексом без мутекса? бред.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 22:20
Я тоже не могу уловить ваши рассуждения. У вас проблема с Mutex. Выше вы говорили что лочится он в потоке, А разлочивается хз где. И дальше говорите что его вообще может не быть.

Как может существовать поток с мутексом без мутекса? бред.

Проблема была не с мутексом. Проблема с разными нитями запускаемыми одним и тем же QThread. Поскольку после запуска, завершения и снова запуска нити разные

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

в разных случаях, в зависимости от конфигурации, один и тот QThread может обслуживать разные плагины - в одних есть необходимость синхронизации, в других нет - теперь понятно?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 14, 2014, 22:33
Гурман, посмотрите на QThreadPool, он вам больше подайдет.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 22:38
Гурман, посмотрите на QThreadPool, он вам больше подайдет.

спс, но есть сомнения, что это поможет - проблема в реализации QThread, а QThreadPool скорее всего опирается на QThread

да и приложение перепахивать уже не с руки


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: vulko от Ноябрь 14, 2014, 22:43
Проблема с разными нитями запускаемыми одним и тем же QThread.

а?! ... а?! что?! где?! ... это взрыв мозга)))

Поскольку после запуска, завершения и снова запуска нити разные

нужно почаще общаться с капитаном очевидность!)))
после того как поток завершается, он как бы умирает. так что это так и должно быть.
я потому и предлагал вариант потока с while(running)


поток с мутексом без мутекса существовать не может

очередной взрыв мозга)))


поэтому переносить мутекс в run() никак нельзя, ибо этот run может выполнить поток, в котором нет и не нужны никакие мутексы, смотря какой плагин к этому потоку подключен

в разных случаях, в зависимости от конфигурации, один и тот QThread может обслуживать разные плагины - в одних есть необходимость синхронизации, в других нет - теперь понятно?

мне понятно только то, что твой интеллект почему то не позволяет иметь мьютекс, но не лочить его, если не нужно...


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 14, 2014, 22:44
спс, но есть сомнения, что это поможет - проблема в реализации QThread, а QThreadPool скорее всего опирается на QThread
Ну это не проблема QThread, он делает все согласно документации: при вызове start создаёт новый поток, в котором выполняет метод run. При завершении метода run завершается и поток.
Каждый вызов start будет порождать новый поток.
Пул же сразу запускает несколько потоков, которые ждут работу QRunnable и как только она появляется выполняют её. После выполнения работы потоки не завершаются, а ждут новую работу.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 23:26
спс, но есть сомнения, что это поможет - проблема в реализации QThread, а QThreadPool скорее всего опирается на QThread
Ну это не проблема QThread, он делает все согласно документации: при вызове start создаёт новый поток, в котором выполняет метод run. При завершении метода run завершается и поток.
Каждый вызов start будет порождать новый поток.
Пул же сразу запускает несколько потоков, которые ждут работу QRunnable и как только она появляется выполняют её. После выполнения работы потоки не завершаются, а ждут новую работу.

Фишка в том, что не известно заранее, сколько потоков надо порождать. То есть, не известно, сколько плагинов их потребуют. Хотя, может быть, в этом есть рациональное зерно. Но придется тогда расширить функциональность плагинов, они должны сообщать, что будут использовать потоки.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 14, 2014, 23:27
Гурман у вас проблема - не разлоченный мутекс была.
Эта проблема в плохом коде.

Вашу логику вы пояснить не можете. Какая там архитектура хитрая. Почему вам бы тупо не создавать  классы и пихать их тупо в qthread?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 14, 2014, 23:37
Гурман у вас проблема - не разлоченный мутекс была.
Эта проблема в плохом коде.

Вашу логику вы пояснить не можете. Какая там архитектура хитрая. Почему вам бы тупо не создавать  классы и пихать их тупо в qthread?


Я уже пояснил логику. Тупо пихать - не годится. Не известно заранее, что пихать. Приложение всё состоит из плагинов. Их количество и состав могут быть каждый раз разными.

Мутекс сейчас разлочен, всё пока вроде работает как надо. Проблема была в том, что в документации QThread не указано, что каждый последовательный запуск создает новую нить, с новым ID, а не использует предыдущую. Если бы это было указано, я бы изначально иначе построил приложение.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 15, 2014, 09:42
Если бы это было указано, я бы изначально иначе построил приложение.
Как же не указано? :)
В описании метода start говорится, что будет запущена новая нить и в ней выполниться run. В описании метода run говорится, что когда он завершится - нить разрушиться.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 15, 2014, 10:15
они должны сообщать, что будут использовать потоки.
И ещё не очень понятно, для чего такое разделение?
Нужна плагину одна или несколько ниток, ну пусть он их и запускает.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 15, 2014, 11:42
Даже есть не так, то тупо создаёте 4 потока по умолчанию и в них пихаете классы плагинов. Нужно больше - создаёте больше. Нужно удалить плагин - даёте сигнал на удаление КЛАССУ, класс уничтожается, а поток остаётся.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 15, 2014, 11:51
даёте сигнал на удаление КЛАССУ, класс уничтожается, а поток остаётся.
Верес, скажите, вы видите разницу между классами и объектами?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 15, 2014, 14:34
Знаю и вижу. И я имею в виду именно то, о чем пишу :)

А вы видите разницу между объектом и объектом класса?


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 15, 2014, 15:53
Знаю и вижу.
А почему путаете их почти в каждой теме?

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

...даёте сигнал на удаление КЛАССУ, класс уничтожается...


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Bepec от Ноябрь 15, 2014, 16:19
Да именно так ) ибо объектов класса может быть неизвестное количество, согласно количеству плагинов.
Потому я и написал классу, хотя можно перефразировать и написать - отдать сигнал об уничтожении всем имеющимся объектам класса :)


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 15, 2014, 18:20
Если бы это было указано, я бы изначально иначе построил приложение.
Как же не указано? :)
В описании метода start говорится, что будет запущена новая нить и в ней выполниться run. В описании метода run говорится, что когда он завершится - нить разрушиться.


Нифига!

Цитировать
Begins execution of the thread by calling run(), which should be reimplemented in a QThread subclass to contain your code. The operating system will schedule the thread according to the priority parameter. If the thread is already running, this function does nothing.

The effect of the priority parameter is dependent on the operating system's scheduling policy. In particular, the priority will be ignored on systems that do not support thread priorities (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler for more details).

See also run() and terminate().

Look up this member in the source code.

Begins execution == начинает выполнение, это подразумевает, что нить создана.

Цитировать

The starting point for the thread. After calling start(), the newly created thread calls this function. The default implementation simply calls exec().

You can reimplemented this function to do other useful work. Returning from this method will end the execution of the thread.

See also start() and wait().

Look up this member in the source code.

Ни слова про разрушение нити.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Old от Ноябрь 15, 2014, 18:59
Нифига!
Странно вы читает. :)
Я не большой знаток английского, но эту фразу перевел бы так:

Цитировать
Begins execution of the thread by calling run()
Начинает выполнение нить в которой выполняется run.

А про разрушение нити говорится здесь:
Цитировать
Returning from this method will end the execution of the thread.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 15, 2014, 19:08
Нифига!
Странно вы читает. :)
Я не большой знаток английского, но эту фразу перевел бы так:

Цитировать
Begins execution of the thread by calling run()
Начинает выполнение нить в которой выполняется run.

А про разрушение нити говорится здесь:
Цитировать
Returning from this method will end the execution of the thread.


А я знаток. На самом деле. Английский начал учить в 7 лет. На последней работе выпускал техническую документацию на своё же ПО на английском языке для экспорта, переводчик только помогала переварить объемы, несколько сотен страниц. Как эксперт гарантирую - фраза "Begins execution of the thread by calling run()" переводится так: "Начинает выполнение нити вызывая run()" и никак иначе. Фраза "Returning from this method will end the execution of the thread." переводится однозначно "Возврат из этого метода закончит выполнение нити". Про разрушение (destruction, severance) ни слова.


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: kuzulis от Ноябрь 15, 2014, 19:56
Цитата: Гурман
Проблема была в том, что в документации QThread не указано, что каждый последовательный запуск создает новую нить, с новым ID, а не использует предыдущую.

Эмм.. если поток в данный момент есть "is running" то QThread::start() ничего не создаст.

PS: Тред не читал и не вникал об чем спор. :)
PS: И прежде чем выдвигать какие-то гипотезы о том что так оно работает или не так - возьмите и посмотрите сорцы (обращаюсь ко всем, так, к слову, чтобы не разводить тонны флуда). :)


Название: Re: Процесс замерзает при работе интерфейса
Отправлено: Гурман от Ноябрь 15, 2014, 20:07
Цитата: Гурман
Проблема была в том, что в документации QThread не указано, что каждый последовательный запуск создает новую нить, с новым ID, а не использует предыдущую.

Эмм.. если поток в данный момент есть "is running" то QThread::start() ничего не создаст.


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